dom4j解析XML实例

部署运行你感兴趣的模型镜像

最近在做一个电子发票开具(现税控接口更改为同步签章)的功能,用到了dom4j来封装及解析xml报文

一. 封装请求报文

1.报文示例如下:

全部报文格式如下,

<?xml version="1.0" encoding="utf-8"?>

<interface xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.chinatax.gov.cn/tirip/dataspec/interfaces.xsd" version="DZFP1.0">
  <globalInfo>
    <appId>ZZSDZFP</appId>
    <interfaceCode>EI.FPKJ.U.EC.INTRA</interfaceCode>
    <passWord>c8ec925fefRjQzODlFMkZFOTcyODQ2QjEzODk2RjcyNzNEMDNCMjg=</passWord>
    <dataExchangeId>77994cabfd9849de9176</dataExchangeId>
    <fjh/>
    <jqbh/>
    <requestCode/>
    <requestTime>2019-07-15 11:02:48</requestTime>
    <userName>500102191212027426</userName>
    <responseCode>144</responseCode>
  </globalInfo>
  <returnStateInfo>
    <returnCode/>
    <returnMessage/>
  </returnStateInfo>
  <Data>
    <dataDescription>
      <zipCode>0</zipCode>
      <encryptCode>0</encryptCode>
      <codeType>0</codeType>
    </dataDescription>
    <content>PFJFUVVFU1RfRlBLSiBjbGFzcz0iUkVRVUVTVF9GUEtKIj48R0hGTUM+5rWL6K+VMDAxPC9HSEZNQz48R0hGX05TUlNCSC8+PEZLRktIWUhfRktGWUhaSC8+PEZLRkRaX0ZLRkRIPjE1ODUzMTYyMzEzPC9GS0ZEWl9GS0ZESD48WEhGRFpfWEhGREg+5ZOI5bCU5ruo5biC5Y2X5bKX5Yy65rGJ5rC06LevMTcy5Y+3ICAgPC9YSEZEWl9YSEZESD48WEhGS0hZSF9TS0ZZSFpIPuW7uuihjOW8gOWPkeWMuuaUr+ihjCAgMjMwMDE4NjY3NTEwNTA1MDM5NDU8L1hIRktIWUhfU0tGWUhaSD48RlBaTF9ETT41MTwvRlBaTF9ETT48WUZQX0RNLz48WUZQX0hNLz48Qlo+55So5oi357yW56CB77yaMTgyMjQ377yb5b6u5L+h5YWs5LyX5Y+377ya5ZOI5oqV5L6b54Ot5YWs5Y+477yb54Ot6LS55ZKo6K+i77yaODcxMTEyMTPvvJvmlYXpmpzmiqXkv67vvJo4NzAwMDExMO+8m+i0ouWKoeWSqOivou+8mjg3MTExMjE2PC9CWj48S1BZPmFkbWluPC9LUFk+PEZIUj7lkLTmoZA8L0ZIUj48U0tZPmFkbWluPC9TS1k+PFhIUUQ+MDwvWEhRRD48RlBRUUxTSD43Nzk5NGNhYmZkOTg0OWRlOTE3NjwvRlBRUUxTSD48S1BMWD4wPC9LUExYPjxKU0hKPjU2NDUuODk8L0pTSEo+PEhKSkU+NTY0NS44OTwvSEpKRT48SEpTRT4wLjAwPC9ISlNFPjxCTUJfQkJIPjE5LjA8L0JNQl9CQkg+PFNQQk1KQ0JaPjI8L1NQQk1KQ0JaPjxCWVpEMS8+PEJZWkQyLz48RlBfS0pNWFMgY2xhc3M9IkZQX0tKTVg7IiBzaXplPSIyIj48RlBfS0pNWD48U1BNQz7lsYXmsJHng63otLk8L1NQTUM+PFNNLz48U0w+MDwvU0w+PEdHWEg+MjAxOC0yMDE5PC9HR1hIPjxKTERXPuW5s+aWueexszwvSkxEVz48U1BTTC8+PFNQREovPjxTUEpFPjQ3MjAuNjQ8L1NQSkU+PEZQSFhaPjA8L0ZQSFhaPjxIU0pCWj4xPC9IU0pCWj48U0U+MC4wMDwvU0U+PFNQQk0+MTEwMDEwMjAxMDEwMDAwMDAwMDwvU1BCTT48WlhCTS8+PFlIWkNCUz4xPC9ZSFpDQlM+PExTTEJTPjE8L0xTTEJTPjxaWlNUU0dMPuWFjeeojjwvWlpTVFNHTD48S0NFLz48QllaRDEvPjxCWVpEMi8+PC9GUF9LSk1YPjxGUF9LSk1YPjxTUE1DPui/nee6pumHkTwvU1BNQz48U00vPjxTTD4wPC9TTD48R0dYSD4yMDE4LTIwMTk8L0dHWEg+PEpMRFc+5bmz5pa557GzPC9KTERXPjxTUFNMLz48U1BESi8+PFNQSkU+OTI1LjI1PC9TUEpFPjxGUEhYWj4wPC9GUEhYWj48SFNKQlo+MTwvSFNKQlo+PFNFPjAuMDA8L1NFPjxTUEJNPjExMDAxMDIwMTAxMDAwMDAwMDA8L1NQQk0+PFpYQk0vPjxZSFpDQlM+MTwvWUhaQ0JTPjxMU0xCUz4xPC9MU0xCUz48WlpTVFNHTD7lhY3nqI48L1paU1RTR0w+PEtDRS8+PEJZWkQxLz48QllaRDIvPjwvRlBfS0pNWD48L0ZQX0tKTVhTPjwvUkVRVUVTVF9GUEtKPg==</content>
  </Data>
</interface>

content节点为内部请求报文,使用了Base64进行了转码,未加密前的内部报文如下:

<REQUEST_FPKJ class="REQUEST_FPKJ">
  <GHFMC>测试001</GHFMC>
  <GHF_NSRSBH/>
  <FKFKHYH_FKFYHZH/>
  <FKFDZ_FKFDH>15853162313</FKFDZ_FKFDH>
  <XHFDZ_XHFDH>海淀区中关村</XHFDZ_XHFDH>
  <XHFKHYH_SKFYHZH>建行开发区支行 8888888888</XHFKHYH_SKFYHZH>
  <FPZL_DM>51</FPZL_DM>
  <YFP_DM/>
  <YFP_HM/>
  <BZ>用户编码:182247</BZ>
  <KPY>admin</KPY>
  <FHR>鲁班七号</FHR>
  <SKY>admin</SKY>
  <XHQD>0</XHQD>
  <FPQQLSH>77994cabfd9849de9176</FPQQLSH>
  <KPLX>0</KPLX>
  <JSHJ>5645.89</JSHJ>
  <HJJE>5645.89</HJJE>
  <HJSE>0.00</HJSE>
  <BMB_BBH>19.0</BMB_BBH>
  <SPBMJCBZ>2</SPBMJCBZ>
  <BYZD1/>
  <BYZD2/>
  <FP_KJMXS class="FP_KJMX;" size="2">
    <FP_KJMX>
      <SPMC>居民热费</SPMC>
      <SM/>
      <SL>0</SL>
      <GGXH>2018-2019</GGXH>
      <JLDW>平方米</JLDW>
      <SPSL/>
      <SPDJ/>
      <SPJE>4720.64</SPJE>
      <FPHXZ>0</FPHXZ>
      <HSJBZ>1</HSJBZ>
      <SE>0.00</SE>
      <SPBM>1100102010100000000</SPBM>
      <ZXBM/>
      <YHZCBS>1</YHZCBS>
      <LSLBS>1</LSLBS>
      <ZZSTSGL>免税</ZZSTSGL>
      <KCE/>
      <BYZD1/>
      <BYZD2/>
    </FP_KJMX>
    <FP_KJMX>
      <SPMC>违约金</SPMC>
      <SM/>
      <SL>0</SL>
      <GGXH>2018-2019</GGXH>
      <JLDW>平方米</JLDW>
      <SPSL/>
      <SPDJ/>
      <SPJE>925.25</SPJE>
      <FPHXZ>0</FPHXZ>
      <HSJBZ>1</HSJBZ>
      <SE>0.00</SE>
      <SPBM>1100102010100000000</SPBM>
      <ZXBM/>
      <YHZCBS>1</YHZCBS>
      <LSLBS>1</LSLBS>
      <ZZSTSGL>免税</ZZSTSGL>
      <KCE/>
      <BYZD1/>
      <BYZD2/>
    </FP_KJMX>
  </FP_KJMXS>
</REQUEST_FPKJ>

2. 拼内层报文代码:

public static String getKJFPXml(String type,List<?> clsList, Object obj) {
		Document document = DocumentHelper.createDocument();
		
		if("开票".equals(type)){//开票
			// 发票根节点
			Element fpkjElement = document.addElement("REQUEST_FPKJ");
			addAttribute(fpkjElement, "class", "REQUEST_FPKJ");
			// DzfpBean entityBean = (DzfpBean) obj;
			DzfpFptEntity entityBean = (DzfpFptEntity) obj;

			addChilds(fpkjElement, "GHFMC", Tools.filterNullString(entityBean
					.getGmf_mc()));// "购货方名称"
			addChilds(fpkjElement, "GHF_NSRSBH", Tools.filterNullString(entityBean
					.getGmf_nsrsbh()));// "购货方识别号"
			addChilds(fpkjElement, "FKFKHYH_FKFYHZH", Tools.filterNullString(entityBean
					.getGmf_yhzh()));// "付款方银行及账号"
			addChilds(fpkjElement, "FKFDZ_FKFDH", Tools.filterNullString(entityBean
					.getGmf_dzdh()));// "付款方地址电话"
			addChilds(fpkjElement, "XHFKHYH_SKFYHZH", Tools.filterNullString(entityBean
					.getXsf_yhzh()));// "销货方银行及账号"
			addChilds(fpkjElement, "XHFDZ_XHFDH", Tools.filterNullString(entityBean
					.getXsf_dzdh()));// "销货方地址电话"
			addChilds(fpkjElement, "FPZL_DM", Tools.filterNullString(entityBean
					.getFpzl_dm()));// "发票种类代码"
			addChilds(fpkjElement, "YFP_DM", Tools.filterNullString(entityBean
					.getYfp_dm()));// "原发票代码"
			addChilds(fpkjElement, "YFP_HM", Tools.filterNullString(entityBean
					.getYfp_hm()));// "原发票号码"
			addChilds(fpkjElement, "BZ", Tools.filterNullString(entityBean
					.getBz()));// "备注"
			addChilds(fpkjElement, "KPY", Tools.filterNullString(entityBean
					.getKpr()));// "开票人"
			addChilds(fpkjElement, "FHR", Tools.filterNullString(entityBean
					.getFhr()));// "复核人"
			addChilds(fpkjElement, "SKY", Tools.filterNullString(entityBean
					.getSkr()));// "收款人"
			addChilds(fpkjElement, "XHQD", Tools.filterNullString(entityBean
					.getQd_bz()));// "清单标识"
			addChilds(fpkjElement, "FPQQLSH", Tools.filterNullString(entityBean
					.getFpqqlsh()));// "请求流水号"
			addChilds(fpkjElement, "KPLX", Tools.filterNullString(entityBean
					.getKplx()));// "开票类型"
			addChilds(fpkjElement, "JSHJ", Tools.filterNullString(entityBean
					.getJshj()));// "价税合计金额"
			addChilds(fpkjElement, "HJJE", Tools
					.filterNullString(entityBean.getHjje()));// "合计金额"
			addChilds(fpkjElement, "HJSE", Tools
					.filterNullString(entityBean.getHjse()));// "合计税额"
			addChilds(fpkjElement, "BMB_BBH", Tools.filterNullString(entityBean.getBmb_bbh()));// "编码表版本号"
			addChilds(fpkjElement, "SPBMJCBZ", Tools.filterNullString(entityBean
					.getSpbmjcbz()));// "商品编码简称标志"
			addChilds(fpkjElement, "BYZD1", Tools.filterNullString(entityBean
					.getByzd1()));// "备用字段 1"
			addChilds(fpkjElement, "BYZD2", Tools.filterNullString(entityBean
					.getByzd2()));// "备用字段 2"
			Element fpxmxxElement = addChild(fpkjElement, "FP_KJMXS", null);

			addAttribute(fpxmxxElement, "class", "FP_KJMX;");
			addAttribute(fpxmxxElement, "size", "" + clsList.size());

			// List<DzfpBean> entityList = (List<DzfpBean>) clsList;
			List<DzfpXmxxEntity> entityList = (List<DzfpXmxxEntity>) clsList;

			for (DzfpXmxxEntity dzfpBean : entityList) {
				Element fpxmxxElements = addChild(fpxmxxElement, "FP_KJMX",
						null);

				addChilds(fpxmxxElements, "SPMC",Tools.filterNullString(dzfpBean.getXmmc())); // 商品名称
				addChilds(fpxmxxElements, "SM",Tools.filterNullString(dzfpBean.getSm())); // 税目
				addChilds(fpxmxxElements, "SL",Tools.filterNullString(dzfpBean.getSl()));// 税率
				addChilds(fpxmxxElements, "GGXH",Tools.filterNullString(dzfpBean.getGgxh()));// 规格型号
				addChilds(fpxmxxElements, "JLDW",Tools.filterNullString(dzfpBean.getJldw())); // 计量单位
				addChilds(fpxmxxElements, "SPSL",Tools.filterNullString(dzfpBean.getXmsl()));// 商品数量
				addChilds(fpxmxxElements, "SPDJ",Tools.filterNullString(dzfpBean.getXmdj()));// 商品单价
				addChilds(fpxmxxElements, "SPJE",Tools.filterNullString(dzfpBean.getXmje()));// 商品金额
				addChilds(fpxmxxElements, "FPHXZ",Tools.filterNullString(dzfpBean.getFphxz()));// 发票行性质
				addChilds(fpxmxxElements, "HSJBZ",Tools.filterNullString(dzfpBean.getHsbz()));// 含税价标志
				addChilds(fpxmxxElements, "SE",Tools.filterNullString(dzfpBean.getSe()));// 税额
				addChilds(fpxmxxElements, "SPBM",Tools.filterNullString(dzfpBean.getSpbm()));// 商品编码
				addChilds(fpxmxxElements, "ZXBM",Tools.filterNullString(dzfpBean.getZxbm()));// 自行编码
				addChilds(fpxmxxElements, "YHZCBS",Tools.filterNullString(dzfpBean.getYhzcbs()));// 优惠政策标识
				addChilds(fpxmxxElements, "LSLBS",Tools.filterNullString(dzfpBean.getLslbs()));// 零税率标识
				addChilds(fpxmxxElements, "ZZSTSGL",Tools.filterNullString(dzfpBean.getZzstsgl()));// 增值税特殊管理
				addChilds(fpxmxxElements, "KCE",Tools.filterNullString(dzfpBean.getKce()));// 扣除额
				addChilds(fpxmxxElements, "BYZD1",Tools.filterNullString(dzfpBean.getByzd1()));// 备用字段
				addChilds(fpxmxxElements, "BYZD2",Tools.filterNullString(dzfpBean.getByzd2()));// 备用字段
			}
		}else{//签章
			// 发票根节点
			Element dzfpElement = document.addElement("REQUEST_FPQZ");
			addAttribute(dzfpElement, "class", "REQUEST_FPQZ");
			
			// 发票签章信息
			try {
				addChilds(dzfpElement, "FPQZ_INFO",Tools.filterNullString(
						encodeStr("SJLY"+(char)2+"06"+(char)3+"FPLX"+(char)2+"1")));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//通过键值对的方式来扩展,键与 值之间用(char)2 分隔,键值对 之间用(char)3 分隔。 组装好后,再加一层 base64
			// 发票头
			Element fptElement = addChild(dzfpElement, "FPQZ_FPT", null);
			addAttribute(fptElement, "class", "FPQZ_FPT");

			// DzfpBean entityBean = (DzfpBean) obj;
			DzfpFptEntity entityBean = (DzfpFptEntity) obj;

			addChilds(fptElement, "FPQQLSH", Tools.filterNullString(entityBean
					.getFpqqlsh()));// "发票请求流水号"
			addChilds(fptElement, "KPLX", Tools.filterNullString(entityBean
					.getKplx()));// "开票类型"
			addChilds(fptElement, "DKBZ", Tools.filterNullString(entityBean
					.getDkbz()));// "代开标志"
			addChilds(fptElement, "SGBZ", Tools.filterNullString(entityBean
					.getSgbz()));// "收购标志"
			addChilds(fptElement, "BMB_BBH", Tools.filterNullString(entityBean
					.getBmb_bbh()));// "编码表版本号"
			addChilds(fptElement, "QDBZ", Tools.filterNullString(entityBean
					.getQd_bz()));// "清单标志"
			addChilds(fptElement, "QDXMMC", Tools.filterNullString(entityBean
					.getQd_fpxmmc()));// "清单发票项目名称"
			
			
			addChilds(fptElement, "XSF_NSRSBH", Tools.filterNullString(entityBean
					.getXsf_nsrsbh()));// "销售方纳税人识别号"
			addChilds(fptElement, "XSF_MC", Tools.filterNullString(entityBean
					.getXsf_mc()));// "销售方名称"
			addChilds(fptElement, "XSF_DZDH", Tools.filterNullString(entityBean
					.getXsf_dzdh()));// "销售方地址、电话"
			addChilds(fptElement, "XSF_YHZH", Tools.filterNullString(entityBean
					.getXsf_yhzh()));// "销售方银行账号"
			addChilds(fptElement, "GMF_NSRSBH", Tools.filterNullString(entityBean
					.getGmf_nsrsbh()));// "购买方纳税人识别号"
			addChilds(fptElement, "GMF_MC", Tools.filterNullString(entityBean
					.getGmf_mc()));// "购买方名称"
			addChilds(fptElement, "GMF_DZDH", Tools.filterNullString(entityBean
					.getGmf_dzdh()));// "购买方地址、电话"
			addChilds(fptElement, "GMF_YHZH", Tools.filterNullString(entityBean
					.getGmf_yhzh()));// "购买方银行账号"
			addChilds(fptElement, "GMF_SJ", Tools.filterNullString(entityBean
					.getGmf_sj()));// "购买方手机"
			addChilds(fptElement, "GMF_EMAIL", Tools.filterNullString(entityBean
					.getGmf_email()));// "购买方邮箱"
			addChilds(fptElement, "KPR", Tools
					.filterNullString(entityBean.getKpr()));// "开票人"
			addChilds(fptElement, "SKR", Tools
					.filterNullString(entityBean.getSkr()));// "收款人"
			addChilds(fptElement, "FHR", Tools
					.filterNullString(entityBean.getFhr()));// "复核人"
			addChilds(fptElement, "YFP_DM", Tools.filterNullString(entityBean
					.getYfp_dm()));// "原发票代码"
			addChilds(fptElement, "YFP_HM", Tools.filterNullString(entityBean
					.getYfp_hm()));// "原发票号码"
			addChilds(fptElement, "JSHJ", Tools.filterNullString(entityBean
					.getJshj()));// "价税合计"
			addChilds(fptElement, "HJJE", Tools.filterNullString(entityBean
					.getHjje()));// "合计金额"
			addChilds(fptElement, "HJSE", Tools.filterNullString(entityBean
					.getHjse()));// "合计税额"
			addChilds(fptElement, "BZ", Tools.filterNullString(entityBean.getBz()));// "备注"
			addChilds(fptElement, "FPZT", Tools.filterNullString("0"));// "发票状态  0:正常发票"
			addChilds(fptElement, "JQBH", PropertiesUtil.getProperNameKey("dzfp.properties", "JQBH"));// "税控设备编号"
			addChilds(fptElement, "FP_DM", Tools.filterNullString(entityBean.getFp_dm()));// "发票代码"
			addChilds(fptElement, "FP_HM", Tools.filterNullString(entityBean.getFp_hm()));// "发票号码"
			addChilds(fptElement, "KPRQ", Tools.filterNullString(entityBean.getKprq()));// "开票日期 YYYYMMDDHHMMSS"
			addChilds(fptElement, "FP_MW", Tools.filterNullString(entityBean.getFp_mw()));// "发票密文"
			addChilds(fptElement, "JYM", Tools.filterNullString(entityBean.getJym()));// "发票校验码"
			addChilds(fptElement, "EWM", Tools.filterNullString(""));// "二维码  目前不需要传值,置空"
			addChilds(fptElement, "PDF_XZFS", Tools.filterNullString("2"));// "1:接口返回 pdf 文件; 2:接口返回 pdf 下载地址; 3:接口同时返回 pdf 文件和 pdf 下载路径 "
			
			Element fpkjElement = addChild(dzfpElement, "FPQZ_XMXXS", null);

			addAttribute(fpkjElement, "class", "FPQZ_XMXX;");
			addAttribute(fpkjElement, "size", "" + clsList.size());

			// List<DzfpBean> entityList = (List<DzfpBean>) clsList;
			List<DzfpXmxxEntity> entityList = (List<DzfpXmxxEntity>) clsList;

			for (DzfpXmxxEntity dzfpBean : entityList) {
				Element fpkjElements = addChild(fpkjElement, "FPQZ_XMXX",
						null);

				addChilds(fpkjElements, "FPHXZ", Tools.filterNullString(dzfpBean
						.getFphxz()));// 发票行性质
				addChilds(fpkjElements, "XMMC", Tools.filterNullString(dzfpBean
						.getXmmc())); // "项目名称"
				addChilds(fpkjElements, "GGXH", Tools.filterNullString(dzfpBean
						.getGgxh()));// "规格型号"
				addChilds(fpkjElements, "DW", Tools.filterNullString(dzfpBean
						.getDw()));// "单位"
				addChilds(fpkjElements, "XMSL", Tools.filterNullString(dzfpBean
						.getXmsl()));// "项目数量"
				addChilds(fpkjElements, "XMDJ", Tools.filterNullString(dzfpBean
						.getXmdj()));// "项目单价"
				addChilds(fpkjElements, "XMJE", Tools.filterNullString(dzfpBean
						.getXmje()));// "项目金额"
				addChilds(fpkjElements, "SL", Tools.filterNullString(dzfpBean
						.getSl()));// "税率"
				addChilds(fpkjElements, "SE", Tools.filterNullString(dzfpBean
						.getSe()));// "税额"
				addChilds(fpkjElements, "HSBZ", Tools.filterNullString(dzfpBean
						.getHsbz()));// "含税标志"

				addChilds(fpkjElements, "SPBM", Tools.filterNullString(dzfpBean
						.getSpbm()));// 商品编码
				addChilds(fpkjElements, "ZXBM", Tools.filterNullString(dzfpBean
						.getZxbm()));// 自行编码
				addChilds(fpkjElements, "YHZCBS", Tools.filterNullString(dzfpBean
						.getYhzcbs()));// 优惠政策标识
				addChilds(fpkjElements, "LSLBS", Tools.filterNullString(dzfpBean
						.getLslbs()));// 零税率标识
				addChilds(fpkjElements, "ZZSTSGL", Tools.filterNullString(dzfpBean
						.getZzstsgl()));// 增值税特殊管理
				addChilds(fpkjElements, "KCE", Tools.filterNullString(dzfpBean
						.getKce()));// 扣除额
			}
			
		}
		

		String str = document.getRootElement().asXML();
		return str;
	}

3. 外层报文+内层报文:

/**
	 * 外层报文+内层报文
	 * @param lx 操作类型
	 * @param contentXML 内层报文-加密
	 * @return
	 */
	public static String getAllXml(String type,String contentXML,DzfpFptEntity entityBean){
		Document document = DocumentHelper.createDocument();			  
		Element rootElement = document.addElement("interface");
		rootElement.addAttribute("xmlns", "");
		rootElement.addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
		rootElement.addAttribute("xsi:schemaLocation", "http://www.chinatax.gov.cn/tirip/dataspec/interfaces.xsd");
		rootElement.addAttribute("version", "DZFP1.0");
		
		Element fptElement = rootElement.addElement("globalInfo");
		
		if("开票".equals(type)){//开票
			/**
			 * 应用标识: 服务器自开票版:A16D8DBD18EDDD80 税控组件开票版:AA0DDF541B152FBA
			 */
			addChilds(fptElement, "appId",Tools.filterNullString("ZZSDZFP"));
			addChilds(fptElement, "interfaceCode",Tools.filterNullString("EI.FPKJ.U.EC.INTRA"));// 接口编码
			addChilds(fptElement, "userName",PropertiesUtil.getProperNameKey("dzfp.properties", "userName"));// 用户编码
			addChilds(fptElement, "passWord",Tools.filterNullString(new CreateXml().getUUID(10).toString()+base(new CreateXml().getUUID(10).toString()+PropertiesUtil.getProperNameKey("dzfp.properties", "registratCode"))));// 请求方密码:10位随机数+Base64({(10位随机数+请求方注册码)MD5})
			addChilds(fptElement, "requestCode",PropertiesUtil.getProperNameKey("dzfp.properties", "requestCode"));// 数据交换请求发出方代码(用户编码)
			addChilds(fptElement, "requestTime",Tools.filterNullString(getDate2()));// 数据交换请求发出时间
			addChilds(fptElement, "responseCode",PropertiesUtil.getProperNameKey("dzfp.properties", "responseCode"));// 数据交换请求接受方代码
			addChilds(fptElement, "dataExchangeId",entityBean.getFpqqlsh());// 数据交换流水号,与内层报文一致
			
			addChilds(fptElement, "fjh",Tools.filterNullString(""));// 分机号
			addChilds(fptElement, "jqbh",Tools.filterNullString(""));// 开票分机号
		}else{//签章
			addChilds(fptElement, "terminalCode",PropertiesUtil.getProperNameKey("dzfp.properties", "terminalCode"));// 0bs架构 1 cs架构
			/**
			 * 应用标识: 服务器自开票版:A16D8DBD18EDDD80 税控组件开票版:AA0DDF541B152FBA
			 */
			addChilds(fptElement, "appId",PropertiesUtil.getProperNameKey("dzfp.properties", "appId"));
			addChilds(fptElement, "version",PropertiesUtil.getProperNameKey("dzfp.properties", "version"));// 版本
			addChilds(fptElement, "interfaceCode",Tools.filterNullString("ECXML.FPQZ.BC.E.INV"));// 接口编码
			addChilds(fptElement, "userName",PropertiesUtil.getProperNameKey("dzfp.properties", "userName"));// 用户编码
			addChilds(fptElement, "passWord",Tools.filterNullString(new CreateXml().getUUID(10).toString()+base(new CreateXml().getUUID(10).toString()+PropertiesUtil.getProperNameKey("dzfp.properties", "registratCode"))));// 请求方密码:10位随机数+Base64({(10位随机数+请求方注册码)MD5})
			addChilds(fptElement, "taxpayerId",PropertiesUtil.getProperNameKey("dzfp.properties", "taxpayerId"));
			addChilds(fptElement, "authorizationCode",PropertiesUtil.getProperNameKey("dzfp.properties", "authorizationCode"));// 纳税人授权码-10位
			
			addChilds(fptElement, "requestCode",PropertiesUtil.getProperNameKey("dzfp.properties", "requestCode"));// 数据交换请求发出方代码(用户编码)
			addChilds(fptElement, "requestTime",Tools.filterNullString(getDate2()));// 数据交换请求发出时间
			addChilds(fptElement, "responseCode",PropertiesUtil.getProperNameKey("dzfp.properties", "responseCode"));// 数据交换请求接受方代码
			addChilds(fptElement, "dataExchangeId",entityBean.getFpqqlsh());// 数据交换流水号(YYYYMMDD)+9位序列号
		}
		
		Element sponse = rootElement.addElement("returnStateInfo");
		addChilds(sponse, "returnCode",Tools.filterNullString(""));
		addChilds(sponse, "returnMessage",Tools.filterNullString(""));
		
		Element data = rootElement.addElement("Data");
		Element data1 = data.addElement("dataDescription");
		if("开票".equals(type)){//开票
			addChilds(data1, "zipCode",Tools.filterNullString("0"));// 0:不压缩 1:压缩 (用GZip压缩)
			addChilds(data1, "encryptCode",Tools.filterNullString("0"));// 加密方式代码
			addChilds(data1, "codeType",Tools.filterNullString("0"));// 加密方式代码
		}else{//签章
			addChilds(data1, "zipCode",Tools.filterNullString("0"));// 0:不压缩 1:压缩 (用GZip压缩)
			addChilds(data1, "encryptCode",Tools.filterNullString("2"));// 加密方式代码
			addChilds(data1, "codeType",Tools.filterNullString("CA"));// 加密方式代码
		}
		addChilds(data, "content",Tools.filterNullString(contentXML));
		document.getRootElement().asXML();
		document.setXMLEncoding("utf-8"); // 默认utf-8
		StringWriter sw = new StringWriter();
		try {
			document.write(sw);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return sw.toString();
	}
        /**
	 * 
	 * 添加孩子节点元素
	 * 
	 * @param parent
	 *            父节点
	 * @param childName
	 *            孩子节点名称
	 * @param childValue
	 *            孩子节点值
	 * @return 新增节点
	 */
	public static Element addChild(Element parent, String childName,
			String childValue) {
		Element element = parent.addElement(childName);// 添加节点元素
		element.setText(childValue == null ? "" : childValue); // 为元素设值
		return element;

	}

	/**
	 * 
	 * 添加孩子节点元素
	 * 
	 * @param parent
	 *            父节点
	 * @param childName
	 *            孩子节点名称
	 * @param childValue
	 *            孩子节点值
	 * @return 新增节点
	 */
	public static Element addChilds(Element parent, String childName,
			String childValue) {
		Element element = parent.addElement(childName);// 添加节点元素
		if (childValue != null && !childValue.isEmpty()) {
			element.setText(childValue == null ? "" : childValue); // 为元素设值
		}
		return element;
	}

	/**	
	 * @param parent
	 * @param attriName
	 * @param attriValue
	 */
	public static void addAttribute(Element parent, String attriName,
			String attriValue) {
		if (attriName != null && !attriName.isEmpty()) {
			if (attriValue != null && !attriValue.isEmpty()) {
				parent.addAttribute(attriName, attriValue == null ? ""
						: attriValue);// 添加节点元素
			}
		}
	}

以上,是请求报文封装,只看报文封装,忽略数据部分,中间涉及的工具类贴在最后。

二. 解析返回报文

1.返回报文格式如下

<?xml version="1.0" encoding="utf-8"?>

<interface> 
  <globalInfo> 
    <appId>ZZSDZFP</appId>  
    <interfaceCode>EI.FPKJ.U.EC.INTRA</interfaceCode>  
    <userName>500102191212027426</userName>  
    <passWord>c8ec925fefRjQzODlFMkZFOTcyODQ2QjEzODk2RjcyNzNEMDNCMjg=</passWord>  
    <requestCode/>  
    <requestTime>2019-07-15 11:02:48</requestTime>  
    <responseCode>144</responseCode>  
    <dataExchangeId>77994cabfd9849de9176</dataExchangeId>  
    <fjh/>  
    <jqbh>661619997746</jqbh> 
  </globalInfo>  
  <returnStateInfo> 
    <returnCode>0000</returnCode>  
    <!--电子发票返回信息描述:发票开具成功-->
    <returnMessage>5Y+R56Wo5byA5YW35oiQ5Yqf</returnMessage> 
  </returnStateInfo>  
  <Data> 
    <content>PFJFU1BPTlNFX0ZQS0ogY2xhc3M9IlJFU1BPTlNFX0ZQS0oiPgogIDxSRVRVUk5DT0RFPjAwMDA8L1JFVFVSTkNPREU+CiAgPFJFVFVSTk1FU1NBR0U+5oiQ5Yqf77yBPC9SRVRVUk5NRVNTQUdFPgogIDxISkJIU0pFPjU2NDUuODk8L0hKQkhTSkU+CiAgPEhKU0U+MC4wMDwvSEpTRT4KICA8S1BSUT4yMDE5MDcxNTExMDg0ODwvS1BSUT4KICA8U1NZRj4yMDE5MDc8L1NTWUY+CiAgPEZQX0RNPjE1MDAwNDUyODg4ODwvRlBfRE0+CiAgPEZQX0hNPjY4MzE0MjkwPC9GUF9ITT4KICA8WEhRREJaPk48L1hIUURCWj4KICA8UkVUQ09ERT4wMDAwPC9SRVRDT0RFPgogIDxGV01XPiZsdDstKi82OTUvMDkvJmx0OzYzNDAwNS0mbHQ7LzQ2LzUqNTE4NDQ3Jmx0Oy8vOCs4MzY1MjQzOTg5Jmx0OzU5LTUzOS8rOComZ3Q7LzImbHQ7NzQvLSs4Kjk0NyoxMTUtNjU0MS80Ki8zKy00NyZsdDsvLzgrODM2NTI0Mzk4Jmd0OzczLzwvRldNVz4KICA8SllNPjU3ODU3MjMyNzY0MDA2NzgzMDcyPC9KWU0+CiAgPFNaUU0+TUlJQk9nWUpLb1pJaHZjTkFRY0NvSUlCS3pDQ0FTY0NBUUV4Q3pBSkJnVXJEZ01DR2dVQU1Bc0dDU3FHU0liM0RRRUhBVEdDQVFZd2dnRUNBZ0VCTUdBd1ZURUxNQWtHQTFVRUJoTUNZMjR4RFRBTEJnTlZCQXNlQkFCREFFRXhEVEFMQmdOVkJBZ2VCRk1YVHF3eEdUQVhCZ05WQkFNZUVFNHRWdjE2RGxLaGk2U0x3VTR0WDhNeERUQUxCZ05WQkFjZUJGTVhUcXdDQndJQkFBQUNUVzB3Q1FZRkt3NERBaG9GQURBTkJna3Foa2lHOXcwQkFRRUZBQVNCZ0hDOVBsSDBSWVlQQmxJYnhWK0ZvUmNSU0RERGY5dWV0dzNySi9hZjhPZGhnTnJRTGFMTi94SEpRYUNuTzFKVHRha3N5ckNEVk9hb0U1Tjd2YUk4Y25WdHhLUDcvaFJYYjMrd0VxcWlYU0pUNVpnUWVUeURYQnB3L2tNK1UrcUlET3hWMHQvQXZHZVhlRXpkUWVFSWZ0YjdMWU12RHdqdSs5TkdhK1hncWN6WDwvU1pRTT4KICA8RVdNPlFrM0NBd0FBQUFBQUFENEFBQUFvQUFBQVN3QUFBRXNBQUFBQkFBRUFBQUFBQUlRREFBQUFBQUFBQUFBQUFBQUFBQUFDQUFBQUFBQUEvLy8vLy8vLy8vLy8vLy8vLy8vZ0FBQUFBekF3dzhQRERNd2dBQUFBQXpBd3c4UERETXdnQUFBLzgvQXpQQVBEREEvZ0FBQS84L0F6UEFQRERBL2dBQUF3TThQODhQTTh6RHdnQUFBd004UDg4UE04ekR3Z0FBQXdNekF3QU0vQXp3RGdBQUF3TXpBd0FNL0F6d0RnQUFBd00vTS9Bei9QQUQ4Z0FBQXdNL00vQXovUEFEOGdBQUEvOHpETUFERHdQd01nQUFBLzh6RE1BRER3UHdNZ0FBQUFBOHdEOHc4QU16TWdBQUFBQTh3RDh3OEFNek1nQUFELy96OHo4ekRQUHd3Z0FBRC8vejh6OHpEUFB3d2dBQUQvOEFEL0E4L3pBQUFnQUFELzhBRC9BOC96QUFBZ0FBQXpEd3p3enc4UEQ4d2dBQUF6RHd6d3p3OFBEOHdnQUFEUDhBRFA4UHp6QU13Z0FBRFA4QURQOFB6ekFNd2dBQUFNekQ4TUR6UERNL01nQUFBTXpEOE1EelBETS9NZ0FBQXo4UEQ4L3pQRDhNOGdBQUF6OFBEOC96UEQ4TThnQUFBd3p3d3d6TURBTUF6Z0FBQXd6d3d3ek1EQU1BemdBQUFEdy9QL0RBL0RNdzhnQUFBRHcvUC9EQS9ETXc4Z0FBRC9Eek16ODgvLzhNOGdBQUQvRHpNejg4Ly84TThnQUFERHd3L004d0RQd0F3Z0FBRER3dy9NOHdEUHdBd2dBQUFNL0F3UHo4UDh6TURnQUFBTS9Bd1B6OFA4ek1EZ0FBRHdNQU13UC9Nek1NTWdBQUR3TUFNd1AvTXpNTU1nQUFBRC84LzhBQXovd0R3Z0FBQUQvOC84QUF6L3dEd2dBQUREd0RBRDhQTXpNOEFnQUFERHdEQUQ4UE16TThBZ0FBQUQvOHpNd0FERDg4L2dBQUFELzh6TXdBREQ4OC9nQUFBODh3d1BBenpEQVBBZ0FBQTg4d3dQQXp6REFQQWdBQUR3RHdNUERNL3pNL3dnQUFEd0R3TVBETS96TS93Z0FBREFBTVBEd0FERDhNOGdBQURBQU1QRHdBREQ4TThnQUFBOC93d004OE1BL0F6Z0FBQTgvd3dNODhNQS9BemdBQUQvdzg4L016OEQ4UDhnQUFEL3c4OC9NejhEOFA4Z0FBRE16TU04L0QvejhQQWdBQURNek1NOC9EL3o4UEFnQUFBOHd3RDh6UHpNelAvZ0FBQTh3d0Q4elB6TXpQL2dBQUQvLzhBRFBBdzhQLy9nQUFELy84QURQQXc4UC8vZ0FBQUFBek16TXpNek1BQWdBQUFBQXpNek16TXpNQUFnQUFBLzh6L0RBQS84OC84Z0FBQS84ei9EQUEvODgvOGdBQUF3TS84d3p6QU04d01nQUFBd00vOHd6ekFNOHdNZ0FBQXdNOERNUER3OE13TWdBQUF3TThETVBEdzhNd01nQUFBd00vek13L0EvTXdNZ0FBQXdNL3pNdy9BL013TWdBQUEvODgvQXp6RDhNLzhnQUFBLzg4L0F6ekQ4TS84Z0FBQUFBOC9ERHpQTU1BQWdBQUFBQTgvRER6UE1NQUFnQUFBPTwvRVdNPgo8L1JFU1BPTlNFX0ZQS0o+</content>  
    <dataDescription> 
      <zipCode>0</zipCode>  
      <encryptCode>0</encryptCode>  
      <codeType>0</codeType> 
    </dataDescription> 
  </Data> 
</interface>

2.返回报文数据部分已加密,未加密内容如下

<RESPONSE_FPKJ class="RESPONSE_FPKJ">
  <RETURNCODE>0000</RETURNCODE>
  <RETURNMESSAGE>鎴愬姛锛?/RETURNMESSAGE>
  <HJBHSJE>5645.89</HJBHSJE>
  <HJSE>0.00</HJSE>
  <KPRQ>20190715110848</KPRQ>
  <SSYF>201907</SSYF>
  <FP_DM>150004528888</FP_DM>
  <FP_HM>68314290</FP_HM>
  <XHQDBZ>N</XHQDBZ>
  <RETCODE>0000</RETCODE>
  <FWMW>&lt;-*/695/09/&lt;634005-&lt;/46/5*518447&lt;//8+8365243989&lt;59-539/+8*&gt;/2&lt;74/-+8*947*115-6541/4*/3+-47&lt;//8+836524398&gt;73/</FWMW>
  <JYM>57857232764006783072</JYM>
  <SZQM>MIIBOgYJKoZIhvcNAQcCoIIBKzCCAScCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCAQYwggECAgEBMGAwVTELMAkGA1UEBhMCY24xDTALBgNVBAseBABDAEExDTALBgNVBAgeBFMXTqwxGTAXBgNVBAMeEE4tVv16DlKhi6SLwU4tX8MxDTALBgNVBAceBFMXTqwCBwIBAAACTW0wCQYFKw4DAhoFADANBgkqhkiG9w0BAQEFAASBgHC9PlH0RYYPBlIbxV+FoRcRSDDDf9uetw3rJ/af8OdhgNrQLaLN/xHJQaCnO1JTtaksyrCDVOaoE5N7vaI8cnVtxKP7/hRXb3+wEqqiXSJT5ZgQeTyDXBpw/kM+U+qIDOxV0t/AvGeXeEzdQeEIftb7LYMvDwju+9NGa+XgqczX</SZQM>
  <EWM>Qk3CAwAAAAAAAD4AAAAoAAAASwAAAEsAAAABAAEAAAAAAIQDAAAAAAAAAAAAAAAAAAACAAAAAAAA///////////////////gAAAAAzAww8PDDMwgAAAAAzAww8PDDMwgAAA/8/AzPAPDDA/gAAA/8/AzPAPDDA/gAAAwM8P88PM8zDwgAAAwM8P88PM8zDwgAAAwMzAwAM/AzwDgAAAwMzAwAM/AzwDgAAAwM/M/Az/PAD8gAAAwM/M/Az/PAD8gAAA/8zDMADDwPwMgAAA/8zDMADDwPwMgAAAAA8wD8w8AMzMgAAAAA8wD8w8AMzMgAAD//z8z8zDPPwwgAAD//z8z8zDPPwwgAAD/8AD/A8/zAAAgAAD/8AD/A8/zAAAgAAAzDwzwzw8PD8wgAAAzDwzwzw8PD8wgAADP8ADP8PzzAMwgAADP8ADP8PzzAMwgAAAMzD8MDzPDM/MgAAAMzD8MDzPDM/MgAAAz8PD8/zPD8M8gAAAz8PD8/zPD8M8gAAAwzwwwzMDAMAzgAAAwzwwwzMDAMAzgAAADw/P/DA/DMw8gAAADw/P/DA/DMw8gAAD/DzMz88//8M8gAAD/DzMz88//8M8gAADDww/M8wDPwAwgAADDww/M8wDPwAwgAAAM/AwPz8P8zMDgAAAM/AwPz8P8zMDgAADwMAMwP/MzMMMgAADwMAMwP/MzMMMgAAAD/8/8AAz/wDwgAAAD/8/8AAz/wDwgAADDwDAD8PMzM8AgAADDwDAD8PMzM8AgAAAD/8zMwADD88/gAAAD/8zMwADD88/gAAA88wwPAzzDAPAgAAA88wwPAzzDAPAgAADwDwMPDM/zM/wgAADwDwMPDM/zM/wgAADAAMPDwADD8M8gAADAAMPDwADD8M8gAAA8/wwM88MA/AzgAAA8/wwM88MA/AzgAAD/w88/Mz8D8P8gAAD/w88/Mz8D8P8gAADMzMM8/D/z8PAgAADMzMM8/D/z8PAgAAA8wwD8zPzMzP/gAAA8wwD8zPzMzP/gAAD//8ADPAw8P//gAAD//8ADPAw8P//gAAAAAzMzMzMzMAAgAAAAAzMzMzMzMAAgAAA/8z/DAA/88/8gAAA/8z/DAA/88/8gAAAwM/8wzzAM8wMgAAAwM/8wzzAM8wMgAAAwM8DMPDw8MwMgAAAwM8DMPDw8MwMgAAAwM/zMw/A/MwMgAAAwM/zMw/A/MwMgAAA/88/AzzD8M/8gAAA/88/AzzD8M/8gAAAAA8/DDzPMMAAgAAAAA8/DDzPMMAAgAAA=</EWM>
</RESPONSE_FPKJ>

3. 返回报文转为map对象取值

public static Map<String, String> readStringXmlOutNJ(String xml) {
		Map<String,String> map = new HashMap<String,String>();
        Document doc = null;
        String s = null;
        try {
            // 将字符串转为XML
            doc = DocumentHelper.parseText(xml); 
            Element root = doc.getRootElement();    //根节点
            map=listNodes(root,map);
    } catch (DocumentException e) {
           e.printStackTrace();
       } catch (Exception e) {
           e.printStackTrace();
       }
       return map;
	}

public static Map<String,String> listNodes(Element node,Map<String,String> map ){  
        //如果当前节点内容不为空,则输出  
        if(!(node.getTextTrim().equals(""))){  
        	map.put(node.getName(), node.getText());  
        }  
        //同时迭代当前节点下面的所有子节点   
        Iterator<Element> iterator = node.elementIterator();  
        while(iterator.hasNext()){  
            Element e = iterator.next();  
            listNodes(e,map);  
        }  
        return map;
    }

4.如果要字符串报文转换Document对象写入新的文件,可这样写(接2)

    /** 
     * 把document对象写入新的文件 
     *  
     * @param document 
     * @throws Exception 
     */  
    public static void writer(Document document) throws Exception {  
        // 紧凑的格式  
        // OutputFormat format = OutputFormat.createCompactFormat();  
        // 排版缩进的格式  
        OutputFormat format = OutputFormat.createPrettyPrint();  
        // 设置编码  
        format.setEncoding("UTF-8");  
        // 创建XMLWriter对象,指定了写出文件及编码格式  
        XMLWriter writer = new XMLWriter(new OutputStreamWriter(  
                new FileOutputStream(new File("src//res.xml")), "UTF-8"), format);  
        // 写入  
        writer.write(document);  
        // 立即写入  
        writer.flush();  
        // 关闭操作  
        writer.close();  
    }  
    public static void fromStrToXml(String xml) throws Exception {  
        Document document = DocumentHelper.parseText(xml);  
        writer(document);  
    }

三.工具类

1.过滤null字符串

        /**
	 * 过滤NULL字符串 
	 * @param Object
	 * @return String
	 */
	public static String filterNullString(Object o){
		if(o == null || "".equals(o) || "null".equals(o)){
			return "";
		}
		return o.toString();
	}

2. 读取配置文件 PropertiesUtil.getProperNameKey("dzfp.properties", "JQBH")

        /**
	 * 
	 * 功能: 根据配置文件名称以及配置文件的键获取值<br>
	 * 约束: 与本函数相关的约束 <br>
	 * 
	 * @param key
	 * @return
	 */
	public static String getProperNameKey(String properName, String key) {
		String keyString = loadPropertyName(properName).getProperty(key);
		if (keyString == null || keyString.isEmpty()) {
			return null;
		}
		return keyString;
	}

	/**
	 * 
	 * 功能: 根据配置文件名称获取配置文件 <br>
	 * 约束: 利用函数调用方法 <br>
	 * 
	 * @return
	 */
	private static Properties loadPropertyName(String properName) {
		Properties prop = new Properties();
		try {
			InputStream is = PropertiesUtil.class.getClassLoader()
					.getResourceAsStream(properName);
			prop.load(is);
			is.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return prop;
	}

中间涉及CA加密的一些内容就不在这写了。

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值