Java XML解析: 序列化 反序列化
Java解析XML的类库很多,本文记录用XStream库对XML的处理
背景
实际开发中,应用报文的格式一般都是JSON和XML;JSON大家都很熟悉(优秀类库:GSON/FastJson/Jackson),但对XML的解析可能并不熟悉,这主要是因为XML一般用于特定的领域:如金融和支付行业,想要和银联及网联对接,XML是少不了的
XStream的使用
XStream是解析XML的一款轻量级类库,简单快捷。下面以网联的交易查询接口为例,记录XML的序列化和反序列化的相关使用方法
报文结构如下:
创建对应的类(具体类信息添加在文末)
创建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());}}
}
- 测试序列化和反序列化的结果
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解析: 序列化 反序列化相关推荐
- Java XML解析工具 JDOM介绍及使用实例
Java XML解析工具 JDOM JDOM介绍 JDOM是一种使用XML的独特Java工具包,用于快速开发XML应用程序. 它的设计包含Java语言的语法乃至语义. JDOM是一个开源项目,它基于树 ...
- java xml解析 jdom_Java XML解析 - 利用JDOM解析XML
Java XML解析 - 利用JDOM解析XML JDOM是一个开源项目,它基于树形结构,利用纯Java的技术对XML文档实现解析.生成.序列化及多种操作.JDOM与DOM非常类似,它是处理XML的纯 ...
- Java XML解析工具 dom4j介绍及使用实例
Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...
- Java XML解析器
使用Apache Xerces解析XML文档 一.技术概述 在用Java解析XML时候,一般都使用现成XML解析器来完成,自己编码解析是一件很棘手的问题,对程序员要求很高,一般也没有专业厂商或者开源组 ...
- java xml解析器_Java XML解析器
java xml解析器 Java XML parser is used to work with xml data. XML is widely used technology to transpor ...
- Java XML解析工具类
Java XML解析工具类 Java解析XML的方式有很多,这里不一一说明了,利用三方jar包,实现了一个XML工具类 本身是有个需求,讲三方公司的XML请求文件中的Response里的属性赋值成ja ...
- java xml解析_XML的理解以及SAX解析流程
XML一般用来存储数据作为数据存储的一种格式 XML还可以用于作为软件的参数配置 这里讲下如何理解java中的相对路径 在java中如何获取当前的路径,当我们知道当前的路径了以后我们就可以使用绝对路径 ...
- java xml解析_Java解析XML(4种方法)
xml文件 <?xml version="1.0" encoding="utf-8" ?><class><student>& ...
- java XML解析
用到的jar包: dom4j-2.0.2 jaxen-1.1.6 1.解析weather.xml <ArrayOfString> <string>河南 南阳</strin ...
最新文章
- https://www.zhihu.com/question/41564604
- python列表的嵌套_Python中关于列表嵌套列表的处理
- oracle有Boolean类型
- 朴素Paxos(Basic Paxos)算法java简易实现
- 使用 Eclipse C/C++ Development Toolkit 开发应用程序
- Opencv——灰度变换、直方图均衡化
- Docker RocketMQ 集群
- sys.dm_exec_query_stats的total_worker_time的单位是微秒还是毫秒
- Spring Boot 事务支持
- Visual Studio 2008 每日提示(十)
- Android 性能优化工具
- 运行时动态的开关 Spring Security
- web测试与app测试异同
- [论文笔记]Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks
- 随机手机号查询易语言代码
- AspectJWeaver
- matlab 求解发动机换算转速,简单一个公式,教你用发动机转速计算车速!
- 黑色星期五 问题描述 有些西方人比较迷信,如果某个月的13号正好是星期五,他们就会觉得不太吉利,用古人的说法,就是“诸事不宜”。请你编写一个程序,统计出在某个特定的年份中,出现了多少次既是13号又
- 计算机网络hdcp是什么意思,NTSC,HDCP ,NTSC/HDCP是什么意思
- 怎么将flv格式转换成mp4,四个步骤完成转换