高效的XML解析与组装-fasterxml

写在前面

最近公司有个需求,需要对接某甲方的老业务系统,传输过来的是ESB报文,也就是XML格式的,响应回去的也是XML报文。虽然目前主流的数据传输还是JSON,但是老的一辈的系统还是避免不了使用XML。XML的解析工具很多,性能各不一样,这里就不一样作介绍了。

初步的解析工具选择-XStream

其实最开始选择的工具是XStream,一开始也没啥问题,功能也实现了,主要是网上很多介绍的也是这个,性能相对比较好,所以就选择了。但是到了性能压测的时候,TPS就惨不忍睹了,低的可怜,我直接上Jmeter的测试报报告图,看了初步有个数。下面我再贴上使用fasterxml解析的性能测试报告,对比一下就知道差距了,毕竟没有对比就没有伤害。XStream的用法可以自行百度了解,这里也不作讲解以及贴代码了。
在这里插入图片描述

fasterxml的使用

下面直接贴代码以及简单简单的介绍。

请求XML

<Message>
 <Message_Header>
  <msgId></msgId>
  <msgRef>66666</msgRef>
  <channel>admin</channel>
  <fromNodeId>admin</fromNodeId>
  <toServiceCode>YW-20200811-0UORY</toServiceCode>
  <externalReferenceNo>444</externalReferenceNo>
  <transactionBranch>88888</transactionBranch>
  <transactionDate>20120918</transactionDate>
  <msgPri>1</msgPri>
  <msgVer>1.0.1</msgVer>
  <replyCode></replyCode>
  <replyText></replyText>
 </Message_Header>
 <Message_Body>
  <request>
         <trcd>aaaaaa</trcd>
         <channo>57</channo>
         <charset>UTF-8</charset>
         <bussid></bussid>
         <branchno>444</branchno>
         <signbranchno>555</signbranchno>
         <immedflag>0</immedflag>
         <lastsndtime></lastsndtime>
         <msgcode></msgcode>
         <msgdesc></msgdesc>
         <jyrq>8月28日</jyrq>
         <jysj>10:38</jysj>
         <name>张三</name>
         <mobile>18007729591</mobile>
         <cdno1></cdno1>
         <cdno2>555555</cdno2>
         <amount>1.00</amount>
         <endbal>8888</endbal>
         <curtype>¥</curtype>
         <mark1></mark1>
         <mark2></mark2>
         <mark3></mark3>
         <mark4>666</mark4>
  </request>
 </Message_Body>
</Message>

pom.xml

   <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-yaml</artifactId>
            <version>2.10.0</version>
    </dependency>

报文的实体类定义

EsbMessageReq.java

@JacksonXmlRootElement(localName = "Message")
@JsonIgnoreProperties(ignoreUnknown = true)
public class EsbMessageReq {

    @JsonProperty("Message_Body")
    private EsbMessageBodyReq esbMessageBodyRequest;

    @JsonProperty("Message_Header")
    private EsbMessageHead esbMessageHead;

    public EsbMessageBodyReq getEsbMessageBodyRequest() {
        return esbMessageBodyRequest;
    }

    public void setEsbMessageBodyRequest(EsbMessageBodyReq esbMessageBodyRequest) {
        this.esbMessageBodyRequest = esbMessageBodyRequest;
    }

    public EsbMessageHead getEsbMessageHead() {
        return esbMessageHead;
    }

    public void setEsbMessageHead(EsbMessageHead esbMessageHead) {
        this.esbMessageHead = esbMessageHead;
    }

EsbMessageHead.java

@JacksonXmlRootElement(localName = "Message_Header")
@JsonIgnoreProperties(ignoreUnknown = true)
public class EsbMessageHead {

    @JsonProperty("msgId")
    private String msgId;

    @JsonProperty("msgRef")
    private String msgRef;

    @JsonProperty("channel")
    private String channel;

    @JsonProperty("fromNodeId")
    private String fromNodeId;

    @JsonProperty("toServiceCode")
    private String toServiceCode;

    @JsonProperty("externalReferenceNo")
    private String externalReferenceNo;

    @JsonProperty("transactionBranch")
    private String transactionBranch;

    @JsonProperty("transactionDate")
    private String transactionDate;

    @JsonProperty("msgPri")
    private String msgPri;

    @JsonProperty("msgVer")
    private String msgVer;

    @JsonProperty("replyCode")
    private String replyCode;

    @JsonProperty("replyText")
    private String replyText;

    public String getMsgId() {
        return msgId;
    }

    public void setMsgId(String msgId) {
        this.msgId = msgId;
    }

    public String getMsgRef() {
        return msgRef;
    }

    public void setMsgRef(String msgRef) {
        this.msgRef = msgRef;
    }

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }

    public String getFromNodeId() {
        return fromNodeId;
    }

    public void setFromNodeId(String fromNodeId) {
        this.fromNodeId = fromNodeId;
    }

    public String getToServiceCode() {
        return toServiceCode;
    }

    public void setToServiceCode(String toServiceCode) {
        this.toServiceCode = toServiceCode;
    }

    public String getExternalReferenceNo() {
        return externalReferenceNo;
    }

    public void setExternalReferenceNo(String externalReferenceNo) {
        this.externalReferenceNo = externalReferenceNo;
    }

    public String getTransactionBranch() {
        return transactionBranch;
    }

    public void setTransactionBranch(String transactionBranch) {
        this.transactionBranch = transactionBranch;
    }

    public String getTransactionDate() {
        return transactionDate;
    }

    public void setTransactionDate(String transactionDate) {
        this.transactionDate = transactionDate;
    }

    public String getMsgPri() {
        return msgPri;
    }

    public void setMsgPri(String msgPri) {
        this.msgPri = msgPri;
    }

    public String getMsgVer() {
        return msgVer;
    }

    public void setMsgVer(String msgVer) {
        this.msgVer = msgVer;
    }

    public String getReplyCode() {
        return replyCode;
    }

    public void setReplyCode(String replyCode) {
        this.replyCode = replyCode;
    }

    public String getReplyText() {
        return replyText;
    }

    public void setReplyText(String replyText) {
        this.replyText = replyText;
    }

EsbMessageBodyReq.java

@JacksonXmlRootElement(localName = "Message_Body")
@JsonIgnoreProperties(ignoreUnknown = true)
public class EsbMessageBodyReq {

    @JsonProperty("request")
    private BodyReq request;

    public BodyReq getRequest() {
        return request;
    }

    public void setRequest(BodyReq request) {
        this.request = request;
    }
}

BodyReq.java

@JacksonXmlRootElement(localName = "request")
@JsonIgnoreProperties(ignoreUnknown = true)
public class BodyReq {    @JsonProperty("trcd")
    private String trcd;

    @JsonProperty("channo")
    private String channo;

    @JsonProperty("charset")
    private String charset;

    @JsonProperty("bussid")
    private String bussid;

    @JsonProperty("branchno")
    private String branchno;

    @JsonProperty("signbranchno")
    private String signbranchno;

    @JsonProperty("immedflag")
    private String immedflag;

    @JsonProperty("lastsndtime")
    private String lastsndtime;

    @JsonProperty("msgcode")
    private String msgcode;

    @JsonProperty("msgdesc")
    private String msgdesc;

    @JsonProperty("jyrq")
    private String jyrq;

    @JsonProperty("jysj")
    private String jysj;

    @JsonProperty("name")
    private String name;

    @JsonProperty("mobile")
    private String mobile;

    @JsonProperty("cdno1")
    private String cdno1;

    @JsonProperty("cdno2")
    private String cdno2;

    @JsonProperty("amount")
    private String amount;

    @JsonProperty("endbal")
    private String endbal;

    @JsonProperty("tdbal")
    private String tdbal;
    
    @JsonProperty("curtype")
    private String curtype;
    
    @JsonProperty("mark1")
    private String mark1;
    
    @JsonProperty("mark2")
    private String mark2;

    @JsonProperty("mark3")
    private String mark3;

    @JsonProperty("mark4")
    private String mark4;

    @JsonProperty("tjd")
    private String tjd;

    @JsonProperty("useWord")
    private String useWord;

    @JsonProperty("RESULT")
    private EsbResult result;

    @JsonProperty("msgcontent")
    private String msgcontent;

    @JsonProperty("trntype")
    private String trntype;

    @JsonProperty("orderNo")
    private String orderNo;

    @JsonProperty("validTime")
    private String validTime;

    @JsonProperty("filename")
    private String filename;

    public String getTrcd() {
        return trcd;
    }

    public void setTrcd(String trcd) {
        this.trcd = trcd;
    }

    public String getChanno() {
        return channo;
    }

    public void setChanno(String channo) {
        this.channo = channo;
    }

    public String getCharset() {
        return charset;
    }

    public void setCharset(String charset) {
        this.charset = charset;
    }

    public String getBussid() {
        return bussid;
    }

    public void setBussid(String bussid) {
        this.bussid = bussid;
    }

    public String getBranchno() {
        return branchno;
    }

    public void setBranchno(String branchno) {
        this.branchno = branchno;
    }

    public String getSignbranchno() {
        return signbranchno;
    }

    public void setSignbranchno(String signbranchno) {
        this.signbranchno = signbranchno;
    }

    public String getImmedflag() {
        return immedflag;
    }

    public void setImmedflag(String immedflag) {
        this.immedflag = immedflag;
    }

    public String getLastsndtime() {
        return lastsndtime;
    }

    public void setLastsndtime(String lastsndtime) {
        this.lastsndtime = lastsndtime;
    }

    public String getMsgcode() {
        return msgcode;
    }

    public void setMsgcode(String msgcode) {
        this.msgcode = msgcode;
    }

    public String getMsgdesc() {
        return msgdesc;
    }

    public void setMsgdesc(String msgdesc) {
        this.msgdesc = msgdesc;
    }

    public String getJyrq() {
        return jyrq;
    }

    public void setJyrq(String jyrq) {
        this.jyrq = jyrq;
    }

    public String getJysj() {
        return jysj;
    }

    public void setJysj(String jysj) {
        this.jysj = jysj;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getCdno1() {
        return cdno1;
    }

    public void setCdno1(String cdno1) {
        this.cdno1 = cdno1;
    }

    public String getCdno2() {
        return cdno2;
    }

    public void setCdno2(String cdno2) {
        this.cdno2 = cdno2;
    }

    public String getAmount() {
        return amount;
    }

    public void setAmount(String amount) {
        this.amount = amount;
    }

    public String getEndbal() {
        return endbal;
    }

    public void setEndbal(String endbal) {
        this.endbal = endbal;
    }

    public String getCurtype() {
        return curtype;
    }

    public void setCurtype(String curtype) {
        this.curtype = curtype;
    }

    public String getMark1() {
        return mark1;
    }

    public void setMark1(String mark1) {
        this.mark1 = mark1;
    }

    public String getMark2() {
        return mark2;
    }

    public void setMark2(String mark2) {
        this.mark2 = mark2;
    }

    public String getMark3() {
        return mark3;
    }

    public void setMark3(String mark3) {
        this.mark3 = mark3;
    }

    public String getMark4() {
        return mark4;
    }

    public void setMark4(String mark4) {
        this.mark4 = mark4;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public String getTdbal() {
        return tdbal;
    }

    public void setTdbal(String tdbal) {
        this.tdbal = tdbal;
    }

    public String getTjd() {
        return tjd;
    }

    public void setTjd(String tjd) {
        this.tjd = tjd;
    }

    public String getUseWord() {
        return useWord;
    }

    public void setUseWord(String useWord) {
        this.useWord = useWord;
    }

    public EsbResult getResult() {
        return result;
    }

    public void setResult(EsbResult result) {
        this.result = result;
    }

    public String getMsgcontent() {
        return msgcontent;
    }

    public void setMsgcontent(String msgcontent) {
        this.msgcontent = msgcontent;
    }

    public String getTrntype() {
        return trntype;
    }

    public void setTrntype(String trntype) {
        this.trntype = trntype;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public String getValidTime() {
        return validTime;
    }

    public void setValidTime(String validTime) {
        this.validTime = validTime;
    }

组装以及解析工具

XmlUtil.java

public class XmlUtils {

    private static final ObjectMapper OBJECT_MAPPER = new XmlMapper();

    /**
     * 将Object 转 XML 字符串
     */
    public static String objectToXmlString(Object object) throws JsonProcessingException {
        // 美化输出的 xml 字符串
        OBJECT_MAPPER.enable(SerializationFeature.INDENT_OUTPUT);
        // 字段为null,自动忽略,不再序列化
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return OBJECT_MAPPER.writeValueAsString(object);
    }

    /**
     * XMl > 将XML字符串转换为JavaBean对象, ObjectMapper还提供了很多重载方法,详情查看源码,这里不一一列举
     */
    public static <T> T xmlStringToObject(String xmlStr, Class<T> tClass) throws IOException {
        // 字段为null,自动忽略,不再序列化
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return OBJECT_MAPPER.readValue(xmlStr, tClass);
    }

}

Test.java

public class Test {

    public static void main(String[] args) {
        String xml = "<Message>\n" +
                " <Message_Header>\n" +
                "  <msgId></msgId>\n" +
                "  <msgRef>66666</msgRef>\n" +
                "  <channel>admin</channel>\n" +
                "  <fromNodeId>admin</fromNodeId>\n" +
                "  <toServiceCode>YW-20200811-0UORY</toServiceCode>\n" +
                "  <externalReferenceNo>444</externalReferenceNo>\n" +
                "  <transactionBranch>88888</transactionBranch>\n" +
                "  <transactionDate>20120918</transactionDate>\n" +
                "  <msgPri>1</msgPri>\n" +
                "  <msgVer>1.0.1</msgVer>\n" +
                "  <replyCode></replyCode>\n" +
                "  <replyText></replyText>\n" +
                " </Message_Header>\n" +
                " <Message_Body>\n" +
                "  <request>\n" +
                "         <trcd>aaaaaa</trcd>\n" +
                "         <channo>57</channo>\n" +
                "         <charset>UTF-8</charset>\n" +
                "         <bussid></bussid>\n" +
                "         <branchno>444</branchno>\n" +
                "         <signbranchno>555</signbranchno>\n" +
                "         <immedflag>0</immedflag>\n" +
                "         <lastsndtime></lastsndtime>\n" +
                "         <msgcode></msgcode>\n" +
                "         <msgdesc></msgdesc>\n" +
                "         <jyrq>8月28日</jyrq>\n" +
                "         <jysj>10:38</jysj>\n" +
                "         <name>张三</name>\n" +
                "         <mobile>18007729591</mobile>\n" +
                "         <cdno1></cdno1>\n" +
                "         <cdno2>555555</cdno2>\n" +
                "         <amount>1.00</amount>\n" +
                "         <endbal>8888</endbal>\n" +
                "         <curtype>¥</curtype>\n" +
                "         <mark1></mark1>\n" +
                "         <mark2></mark2>\n" +
                "         <mark3></mark3>\n" +
                "         <mark4>666</mark4>\n" +
                "  </request>\n" +
                " </Message_Body>\n" +
                "</Message>";

        try {
            EsbMessageReq esbMessageReq = XmlUtils.xmlStringToObject(xml, EsbMessageReq.class);
            System.out.println(esbMessageReq);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

EsbMessageReq{esbMessageBodyRequest=EsbMessageBody{request=BodyReq{trcd=‘aaaaaa’, channo=‘57’, charset=‘UTF-8’, bussid=’’, branchno=‘444’, signbranchno=‘555’, immedflag=‘0’, lastsndtime=’’, msgcode=’’, msgdesc=’’, jyrq=‘8月28日’, jysj=‘10:38’, name=‘张三’, mobile=‘18007729591’, cdno1=’’, cdno2=‘555555’, amount=‘1.00’, endbal=‘8888’, tdbal=‘null’, curtype=‘¥’, mark1=’’, mark2=’’, mark3=’’, mark4=‘666’, tjd=‘null’, useWord=‘null’, result=null, msgcontent=‘null’, trntype=‘null’, orderNo=‘null’, validTime=‘null’, filename=‘null’}}, esbMessageHead=EsbMessageHead{msgId=’’, msgRef=‘66666’, channel=‘admin’, fromNodeId=‘admin’, toServiceCode=‘YW-20200811-0UORY’, externalReferenceNo=‘444’, transactionBranch=‘88888’, transactionDate=‘20120918’, msgPri=‘1’, msgVer=‘1.0.1’, replyCode=’’, replyText=’’}}

在这里顺便贴上优化后的性能压测:
在这里插入图片描述

后记

所以XML解析第三方的库选择对性能有很大影响,在这里极力推荐fasterxml,测试性能TPS大概比XStream快了近40倍左右,有兴趣的可以自行测试,感谢阅读。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值