拓展阅读

config 配置方式概览-8 种配置文件介绍对比 xml/json/proeprties/ini/yaml/TOML/hcl/hocon

config HCL(HashiCorp Configuration Language) 配置文件介绍

config HCL(HashiCorp Configuration Language) 官方文档翻译

config HOCON(Human-Optimized Config Object Notation)配置文件介绍

config ini 配置文件介绍

config properties 配置文件介绍

toml-01-toml 配置文件介绍

XStream java 实现 xml 与对象 pojo 之间的转换

java 实现 xml 与对象 pojo 之间的转换的几种方式 dom4j/xstream/jackson

YAML-01-yml 配置文件介绍

YAML-02-yml 配置文件 java 整合使用 yamlbeans + snakeyaml + jackson-dataformat-yaml

YAML-03-yml 配置文件介绍官方文档翻译

json 专题系列

场景

解析的一段 xml 报文信息:

  [xml]
1
2
3
4
5
6
7
8
<xml> <ToUserName><![CDATA[xxx]]></ToUserName> <FromUserName><![CDATA[xxx]]></FromUserName> <CreateTime>1675747313</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[unsubscribe]]></Event> <EventKey><![CDATA[]]></EventKey> </xml>

下面介绍几种常见的方式。

V1-dom4j

maven 引入

  [xml]
1
2
3
4
5
<dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency>

实现

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.github.houbb.xml.learn; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.DocumentHelper; import org.dom4j.Element; import java.util.*; public class Dmo4jTest { public static void main(String[] args) { String returnMsg = "<xml><ToUserName><![CDATA[yyyy]]></ToUserName>\n" + "<FromUserName><![CDATA[xxxx]]></FromUserName>\n" + "<CreateTime>1675747313</CreateTime>\n" + "<MsgType><![CDATA[event]]></MsgType>\n" + "<Event><![CDATA[unsubscribe]]></Event>\n" + "<EventKey><![CDATA[]]></EventKey>\n" + "</xml>"; try { Document doc = DocumentHelper.parseText(returnMsg); // 指向根节点 Element root = doc.getRootElement(); Iterator it = root.elementIterator(); while (it.hasNext()) { // 一个Item节点 Element element = (Element) it.next(); System.out.println(element.getName() + " : " + element.getTextTrim()); } } catch (DocumentException e) { e.printStackTrace(); } } }

输出日志:

  [plaintext]
1
2
3
4
5
6
ToUserName : yyyy FromUserName : xxxx CreateTime : 1675747313 MsgType : event Event : unsubscribe EventKey :

当然,这样转为 pojo 还需要额外的处理。

针对这一点,有一些工具已经非常成功。

V2-使用 xstream

maven 引入

  [xml]
1
2
3
4
5
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.9</version> </dependency>

java 实现

对应的 XstramWxEventMessage 对象定义如下:

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.github.houbb.xml.learn.dto; import com.thoughtworks.xstream.annotations.XStreamAlias; import java.io.Serializable; @XStreamAlias("xml") public class XstramWxEventMessage implements Serializable { @XStreamAlias("ToUserName") private String toUserName; @XStreamAlias("FromUserName") private String fromUserName; @XStreamAlias("CreateTime") private String createTime; @XStreamAlias("MsgType") private String msgType; @XStreamAlias("Event") private String event; @XStreamAlias("EventKey") private String eventKey; // getter&setter&toString }

我们可以通过 @XStreamAlias 指定字段和类的别名。

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.github.houbb.xml.learn; import com.github.houbb.xml.learn.dto.XstramWxEventMessage; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.io.xml.DomDriver; public class XstramTest { public static void main(String[] args) { // 这是会报错,感觉场景不是很适合 XStream xstream = new XStream(new DomDriver()); xstream.processAnnotations(XstramWxEventMessage.class); XstramWxEventMessage message = new XstramWxEventMessage(); message.setFromUserName("ffff"); message.setToUserName("Xxxx"); String xml = xstream.toXML(message); System.out.println(xml); String returnMsg = "<xml><ToUserName><![CDATA[yyyy]]></ToUserName>\n" + "<FromUserName><![CDATA[xxxx]]></FromUserName>\n" + "<CreateTime>1675747313</CreateTime>\n" + "<MsgType><![CDATA[event]]></MsgType>\n" + "<Event><![CDATA[unsubscribe]]></Event>\n" + "<EventKey><![CDATA[]]></EventKey>\n" + "</xml>"; XstramWxEventMessage fromMessage = (XstramWxEventMessage) xstream.fromXML(returnMsg); System.out.println(fromMessage); } }

输出日志:

  [plaintext]
1
2
3
4
5
6
<xml> <ToUserName>Xxxx</ToUserName> <FromUserName>ffff</FromUserName> </xml> WxEventMessage{toUserName='yyyy', fromUserName='xxxx', createTime='1675747313', msgType='event', event='unsubscribe', eventKey=''}

这样使用起来比较方便,不过对于 xml 这个必须限定指定别称,感觉也挺别扭的。

V3-jaskson

maven

  [xml]
1
2
3
4
5
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> <version>2.9.7</version> </dependency>

java 实现

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import java.io.Serializable; @JsonIgnoreProperties(ignoreUnknown = true) public class JacksonWxEventMessage implements Serializable { @JacksonXmlProperty(localName = "ToUserName") private String toUserName; @JacksonXmlProperty(localName = "FromUserName") private String fromUserName; @JacksonXmlProperty(localName = "CreateTime") private String createTime; @JacksonXmlProperty(localName = "MsgType") private String msgType; @JacksonXmlProperty(localName = "Event") private String event; @JacksonXmlProperty(localName = "EventKey") private String eventKey; // getter&setter&toString }

测试代码

  [java]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import com.fasterxml.jackson.dataformat.xml.XmlMapper; import com.github.houbb.xml.learn.dto.JacksonWxEventMessage; public class JasksonTest { public static void main(String[] args) { String returnMsg = "<xml><ToUserName><![CDATA[yyyy]]></ToUserName>\n" + "<FromUserName><![CDATA[xxxx]]></FromUserName>\n" + "<CreateTime>1675747313</CreateTime>\n" + "<MsgType><![CDATA[event]]></MsgType>\n" + "<Event><![CDATA[unsubscribe]]></Event>\n" + "<EventKey><![CDATA[]]></EventKey>\n" + "</xml>"; try { XmlMapper xmlMapper = new XmlMapper(); JacksonWxEventMessage jacksonWxEventMessage = xmlMapper.readValue(returnMsg, JacksonWxEventMessage.class); System.out.println(jacksonWxEventMessage); } catch (Exception e) { e.printStackTrace(); } } }

总结

实现的方式有多种,选择合适自己业务的即可。