Java解析XML的类库很多,本文记录用XStream库对XML的处理

背景
实际开发中,应用报文的格式一般都是JSON和XML;JSON大家都很熟悉(优秀类库:GSON/FastJson/Jackson),但对XML的解析可能并不熟悉,这主要是因为XML一般用于特定的领域:如金融和支付行业,想要和银联及网联对接,XML是少不了的

XStream的使用
XStream是解析XML的一款轻量级类库,简单快捷。下面以网联的交易查询接口为例,记录XML的序列化和反序列化的相关使用方法

报文结构如下:

  1. 创建对应的类(具体类信息添加在文末)

  2. 创建XStream工具类

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class XmlUtil {/**** @param obj 要序列化的对象* @return 序列化后的xml字符串*/public static String toXml(Object obj) {XStream xStream = new XStream();xStream.autodetectAnnotations(true); // 自动发现注解try {return xStream.toXML(obj);} catch (Exception e) {throw new RuntimeException("Serialization object to xml error: " + e.getMessage());}}/**** @param is XML字符串的字节流* @param targetClazz xml反序列化的目标类* @param <T>* @return 目标类对象*/public static <T> T fromXml(InputStream is, Class<T> targetClazz) {XStream xStream = new XStream();// 设置安全模式XStream.setupDefaultSecurity(xStream);// 允许反序列化的类xStream.allowTypes(new Class[] {TransStatusInquiryResponse.class});xStream.processAnnotations(targetClazz); // 反序列化的类try {return (T) xStream.fromXML(is);} catch (Exception e) {throw new RuntimeException("Deserialization from xml to object error: " + e.getMessage());}}
}
  1. 测试序列化和反序列化的结果
public class Test {public static final String XML_NS = "name_space_string";public static final String ISO_DATE_TIME = "yyyy-MM-dd'T'HH:mm:ss";public static final String responseXml = "<root xmlns=\"name_space_string\">\n" +"  <MsgHeader>\n" +"    <MsgTp>epcc.302.001.01</MsgTp>\n" +"    <IssrId>ICBC00001</IssrId>\n" +"    <Drctn>21</Drctn>\n" +"    <SignSN>87654321</SignSN>\n" +"    <NcrptnSN></NcrptnSN>\n" +"    <DgtlEnvlp></DgtlEnvlp>\n" +"  </MsgHeader>\n" +"  <MsgBody>\n" +"    <SysRtnInf>\n" +"      <SysRtnCd>00000000</SysRtnCd>\n" +"      <SysRtnDesc></SysRtnDesc>\n" +"      <SysRtnTm>2020-11-29T15:41:15</SysRtnTm>\n" +"    </SysRtnInf>\n" +"    <BizInf>\n" +"      <RPFlg>foo</RPFlg>\n" +"      <OriSysRtnCd>foo</OriSysRtnCd>\n" +"      <OriSysRtnDesc>foo</OriSysRtnDesc>\n" +"      <OriBizstsCd></OriBizstsCd>\n" +"      <OriBizStsDesc></OriBizStsDesc>\n" +"      <OriTrxctgy>0115</OriTrxctgy>\n" +"      <OriTrxId>20201128888888888888888800022</OriTrxId>\n" +"      <OriTrxStatus>foo</OriTrxStatus>\n" +"      <DbtrBankId>foo</DbtrBankId>\n" +"      <CdtrBankId>foo</CdtrBankId>\n" +"      <OriTrxAmt>foo</OriTrxAmt>\n" +"      <OriBatchId>foo</OriBatchId>\n" +"      <OriSgnNo>foo</OriSgnNo>\n" +"      <PyerAcctTp>foo</PyerAcctTp>\n" +"      <PyerAcctId>foo</PyerAcctId>\n" +"      <PyerAcctNm>foo</PyerAcctNm>\n" +"      <AcctshrtId>foo</AcctshrtId>\n" +"      <ResfdAcctshrtId>foo</ResfdAcctshrtId>\n" +"    </BizInf>\n" +"  </MsgBody>\n" +"</root>";public static void main(String[] args) {String xmlStr = XmlUtil.toXml(buildRequestObj());System.out.println(xmlStr);System.out.println("--------------------------");TransStatusInquiryResponse inquiryResponse = XmlUtil.fromXml(new ByteArrayInputStream(responseXml.getBytes(StandardCharsets.UTF_8)), TransStatusInquiryResponse.class);System.out.println(inquiryResponse.toString());}private static TransStatusInquiryRequest buildRequestObj() {TransStatusInquiryRequest inquiryRequest = new TransStatusInquiryRequest();inquiryRequest.setXmlns(XML_NS);MsgRequestHeader requestHeader = new MsgRequestHeader();requestHeader.setSndDt(DateTimeFormatter.ofPattern(ISO_DATE_TIME).format(LocalDateTime.now()));requestHeader.setMsgTp("epcc.301.001.01");requestHeader.setIssrId("ICBC00001");requestHeader.setDrctn("11");requestHeader.setSignSn("12345678");requestHeader.setNcrptnSn("");requestHeader.setDgtlEnvlp("");inquiryRequest.setMsgRequestHeader(requestHeader);MsgRequestBody requestBody = new MsgRequestBody();requestBody.setInstgId("12345678901234");requestBody.setRPFlg("2");OriginTrxInfo originTrxInfo = new OriginTrxInfo();originTrxInfo.setOriTrxCtgy("0115");originTrxInfo.setOriTrxId("20201128888888888888888800022");originTrxInfo.setOriTrxDtTm(DateTimeFormatter.ofPattern(ISO_DATE_TIME).format(LocalDateTime.now()));originTrxInfo.setOriAcctTp("00");originTrxInfo.setOrisgnNo("");requestBody.setOriginTrxInfo(originTrxInfo);inquiryRequest.setMsgRequestBody(requestBody);return inquiryRequest;}
}

结果如下:

序列化,组装交易查询的请求报文:
<root xmlns="name_space_string"><MsgHeader><SndDt>2020-11-29T15:46:55</SndDt><MsgTp>epcc.301.001.01</MsgTp><IssrId>ICBC00001</IssrId><Drctn>11</Drctn><SignSN>12345678</SignSN><NcrptnSN></NcrptnSN><DgtlEnvlp></DgtlEnvlp></MsgHeader><MsgBody><InstgId>12345678901234</InstgId><RPFlg>2</RPFlg><OriTrxInf><OriTrxCtgy>0115</OriTrxCtgy><OriTrxId>20201128888888888888888800022</OriTrxId><OriTrxDtTm>2020-11-29T15:46:55</OriTrxDtTm><OriAcctTp>00</OriAcctTp><OrisgnNo></OrisgnNo></OriTrxInf></MsgBody>
</root>--------------------------
反序列化响应报文,结果如下:
TransStatusInquiryResponse(xmlns=name_space_string, msgResponseHeader=MsgResponseHeader(sndDt=null, msgTp=epcc.302.001.01, issrId=ICBC00001, drctn=21, signSn=87654321, ncrptnSn=, dgtlEnvlp=), msgResponseBody=MsgResponseBody(sysRtnInf=SysRtnInf(sysRtnCd=00000000, sysRtnDesc=, sysRtnTm=2020-11-29T15:41:15), bizInf=BizInf(rPFlg=foo, oriSysRtnCd=foo, oriSysRtnDesc=foo, oriBizstsCd=, oriBizStsDesc=, oriTrxctgy=0115, oriTrxId=20201128888888888888888800022, oriTrxStatus=foo, dbtrBankId=foo, cdtrBankId=foo, oriTrxAmt=foo, oriBatchId=foo, oriSgnNo=foo, pyerAcctTp=foo, pyerAcctId=foo, pyerAcctNm=foo, acctshrtId=foo, resfdAcctshrtId=foo)))

请求报文相关的类信息如下:

@Getter
@Setter
@ToString
@XStreamAlias("root") // 对应的XML中的标签名字
public class TransStatusInquiryRequest {@XStreamAlias("xmlns") // 对应的XML中的标签名字@XStreamAsAttribute // 声明root标签的属性private String xmlns;@XStreamAlias("MsgHeader") // 对应的XML中的标签名字private MsgRequestHeader msgRequestHeader;@XStreamAlias("MsgBody") // 对应的XML中的标签名字private MsgRequestBody msgRequestBody;
}@Getter
@Setter
@ToString
@XStreamAlias("MsgHeader")
public class MsgRequestHeader {@XStreamAlias("SndDt")private String sndDt;@XStreamAlias("MsgTp")private String msgTp;@XStreamAlias("IssrId")private String issrId;@XStreamAlias("Drctn")private String drctn;@XStreamAlias("SignSN")private String signSn;@XStreamAlias("NcrptnSN")private String ncrptnSn;@XStreamAlias("DgtlEnvlp")private String dgtlEnvlp;
}@Getter
@Setter
@ToString
@XStreamAlias("MsgBody")
public class MsgRequestBody {@XStreamAlias("InstgId")private String instgId;@XStreamAlias("RPFlg")private String rPFlg;@XStreamAlias("OriTrxInf")private OriginTrxInfo originTrxInfo;
}@Getter
@Setter
@ToString
@XStreamAlias("OriTrxInf")
public class OriginTrxInfo {@XStreamAlias("OriTrxCtgy")private String oriTrxCtgy;@XStreamAlias("OriTrxId")private String oriTrxId;@XStreamAlias("OriTrxDtTm")private String oriTrxDtTm;@XStreamAlias("OriAcctTp")private String oriAcctTp;@XStreamAlias("OrisgnNo")private String orisgnNo;
}

响应报文对应的类信息如下:

@Getter
@Setter
@ToString
@XStreamAlias("root")
public class TransStatusInquiryResponse {// 对响应报文的校验可以使用Java Validation相关注解,非常方便@XStreamAlias("xmlns")@XStreamAsAttributeprivate String xmlns;@XStreamAlias("MsgHeader")private MsgResponseHeader msgResponseHeader;@XStreamAlias("MsgBody")private MsgResponseBody msgResponseBody;
}@Getter
@Setter
@ToString
@XStreamAlias("MsgHeader")
public class MsgResponseHeader {@XStreamAlias("SndDt")private String sndDt;@XStreamAlias("MsgTp")private String msgTp;@XStreamAlias("IssrId")private String issrId;@XStreamAlias("Drctn")private String drctn;@XStreamAlias("SignSN")private String signSn;@XStreamAlias("NcrptnSN")private String ncrptnSn;@XStreamAlias("DgtlEnvlp")private String dgtlEnvlp;
}@Getter
@Setter
@ToString
@XStreamAlias("MsgBody")
public class MsgResponseBody {@XStreamAlias("SysRtnInf")private SysRtnInf sysRtnInf;@XStreamAlias("BizInf")private BizInf bizInf;
}@Getter
@Setter
@ToString
@XStreamAlias("SysRtnInf")
public class SysRtnInf {@XStreamAlias("SysRtnCd")private String sysRtnCd;@XStreamAlias("SysRtnDesc")private String sysRtnDesc;@XStreamAlias("SysRtnTm")private String sysRtnTm;
}@Getter
@Setter
@ToString
@XStreamAlias("BizInf")
public class BizInf {@XStreamAlias("RPFlg")private String rPFlg;@XStreamAlias("OriSysRtnCd")private String oriSysRtnCd;@XStreamAlias("OriSysRtnDesc")private String oriSysRtnDesc;@XStreamAlias("OriBizstsCd")private String oriBizstsCd;@XStreamAlias("OriBizStsDesc")private String oriBizStsDesc;@XStreamAlias("OriTrxctgy")private String oriTrxctgy;@XStreamAlias("OriTrxId")private String oriTrxId;@XStreamAlias("OriTrxStatus")private String oriTrxStatus;@XStreamAlias("DbtrBankId")private String dbtrBankId;@XStreamAlias("CdtrBankId")private String cdtrBankId;@XStreamAlias("OriTrxAmt")private String oriTrxAmt;@XStreamAlias("OriBatchId")private String oriBatchId;@XStreamAlias("OriSgnNo")private String oriSgnNo;@XStreamAlias("PyerAcctTp")private String pyerAcctTp;@XStreamAlias("PyerAcctId")private String pyerAcctId;@XStreamAlias("PyerAcctNm")private String pyerAcctNm;@XStreamAlias("AcctshrtId")private String acctshrtId;@XStreamAlias("ResfdAcctshrtId")private String resfdAcctshrtId;
}

结束

Java XML解析: 序列化 反序列化相关推荐

  1. Java XML解析工具 JDOM介绍及使用实例

    Java XML解析工具 JDOM JDOM介绍 JDOM是一种使用XML的独特Java工具包,用于快速开发XML应用程序. 它的设计包含Java语言的语法乃至语义. JDOM是一个开源项目,它基于树 ...

  2. java xml解析 jdom_Java XML解析 - 利用JDOM解析XML

    Java XML解析 - 利用JDOM解析XML JDOM是一个开源项目,它基于树形结构,利用纯Java的技术对XML文档实现解析.生成.序列化及多种操作.JDOM与DOM非常类似,它是处理XML的纯 ...

  3. Java XML解析工具 dom4j介绍及使用实例

    Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...

  4. Java XML解析器

    使用Apache Xerces解析XML文档 一.技术概述 在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组 ...

  5. java xml解析器_Java XML解析器

    java xml解析器 Java XML parser is used to work with xml data. XML is widely used technology to transpor ...

  6. Java XML解析工具类

    Java XML解析工具类 Java解析XML的方式有很多,这里不一一说明了,利用三方jar包,实现了一个XML工具类 本身是有个需求,讲三方公司的XML请求文件中的Response里的属性赋值成ja ...

  7. java xml解析_XML的理解以及SAX解析流程

    XML一般用来存储数据作为数据存储的一种格式 XML还可以用于作为软件的参数配置 这里讲下如何理解java中的相对路径 在java中如何获取当前的路径,当我们知道当前的路径了以后我们就可以使用绝对路径 ...

  8. java xml解析_Java解析XML(4种方法)

    xml文件 <?xml version="1.0" encoding="utf-8" ?><class><student>& ...

  9. java XML解析

    用到的jar包: dom4j-2.0.2 jaxen-1.1.6 1.解析weather.xml <ArrayOfString> <string>河南 南阳</strin ...

最新文章

  1. https://www.zhihu.com/question/41564604
  2. python列表的嵌套_Python中关于列表嵌套列表的处理
  3. oracle有Boolean类型
  4. 朴素Paxos(Basic Paxos)算法java简易实现
  5. 使用 Eclipse C/C++ Development Toolkit 开发应用程序
  6. Opencv——灰度变换、直方图均衡化
  7. Docker RocketMQ 集群
  8. sys.dm_exec_query_stats的total_worker_time的单位是微秒还是毫秒
  9. Spring Boot 事务支持
  10. Visual Studio 2008 每日提示(十)
  11. Android 性能优化工具
  12. 运行时动态的开关 Spring Security
  13. web测试与app测试异同
  14. [论文笔记]Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks
  15. 随机手机号查询易语言代码
  16. AspectJWeaver
  17. matlab 求解发动机换算转速,简单一个公式,教你用发动机转速计算车速!
  18. 黑色星期五 问题描述   有些西方人比较迷信,如果某个月的13号正好是星期五,他们就会觉得不太吉利,用古人的说法,就是“诸事不宜”。请你编写一个程序,统计出在某个特定的年份中,出现了多少次既是13号又
  19. 计算机网络hdcp是什么意思,NTSC,HDCP ,NTSC/HDCP是什么意思
  20. 怎么将flv格式转换成mp4,四个步骤完成转换

热门文章

  1. 【转】WebService中使用自定义类的解决方法(5种)
  2. Qt程序添加音乐和音效,解决QtCreator中给程序添加音乐失败的问题
  3. 系统/应用优化经验总结及资料整理
  4. TMS320F28335-CAN模块编程
  5. Geogebra下载【linux,MacOS,windows,iOS, Android】
  6. Zxing识别图中二维码实践
  7. 解决mkdocs运行缓慢的问题
  8. 第五章 HFSS的边界条件
  9. java计算机毕业设计计算机实验课程学习系统源码+mysql数据库+系统+lw文档+部署
  10. Tegaki安装指南