目录
日常开发中和外部系统交互方式基本上会选择json格式,但是也不可避免xml格式的交互。xml的解析方式有很多种:jdom,SAX,dom4j,XStream等,相对于其他解析方式,使用XStream的注解方式更简洁更直接,本文描述如何使用XStream注解实现XML和Java对象的相互转换
Maven引入XStream依赖
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.9</version>
</dependency>
XStream常用注解
- @XStreamAlias(“CONDITION”) 指定被注解的元素在xml文件中的标签名
- @XStreamAttribute 指定被注解的属性为标签的属性
- @XStreamOmitField 忽略被注解的属性
- @XStreamImplicit(itemFieldName = “CONDITION”) 指定被注解的List和Map被映射成多个CONDITION标签
xml格式及对应的java对象
xml
<?xml version="1.0" encoding="UTF-8"?>
<MESSAGE>
<DATASET name="WA_COMMON_010000" rmk="数据交互通用信息 ">
<DATA>
<ITEM key="CLUE_SRC_SYS" val="010000" eng="FROM" chn="发起节点的标识" rmk="呵呵" />
<ITEM key="CLUE_DST_SYS" val="110000" eng="TO" chn="服务节点机编号" rmk="" />
<ITEM key="MESSAGE_SEQUENCE" val="010000201103070955330012" eng="MESSAGE_SEQUENCE" chn="消息流水号" rmk="流水号ID" />
<ITEM key="MESSAGE_TYPE" val="140011" eng="MESSAGE_TYPE" chn="消息类型" rmk="通用数据查询请求" />
<ITEM key="BUSINESS_SERVER_TYPE" val="02" eng="BUSINESS_SERVER_TYPE" chn="业务服务类型" rmk="查询业务服务类型(数字)" />
</DATA>
</DATASET>
<DATASET name="WA_COMMON_010010" rmk="查询下发通用信息">
<DATA>
<ITEM key="SEARCH_RESULT_MAXNUM" val="2000" eng="SEARCH_RESULT_MAXNUM" chn="最多总返回条数" />
<ITEM key="SEARCH_ALLOW_ASYN" val="NO" eng="SEARCH_ALLOW_ASYN" chn="是否异步" />
<ITEM key="SERVICE_ID" val="S01000011000010001" rmk="回调服务ID" />
<ITEM key="CLUE_ID" val="0100004001201103070955330023" rmk="查询任务标识(异步查询时才需要)"/>
<ITEM key="SEARCH_RESULT_COUNT" val="1000" eng="SEARCH_RESULT_COUNT" chn="一次查询返回结果数" />
<ITEM key="SEARCH_STRUCTURED" val="YES" eng="SEARCH_STRUCTURED" chn="是否要结构化数据" />
<ITEM key="SEARCH_CONTEXT" val="YES" eng="SEARCH_CONTEXT" chn="是否要附带摘要数据" />
<ITEM key="SEARCH_DETAILOPTIAN" val="NO" eng="SEARCH_DETAILOPTIAN" chn="是否要附带全文数据" />
<CONDITION rel="AND">
<ITEM key="USERNAME" val="12345678" eng="USERNAME" rmk="可同时查出发送方和接收方" fmt="" chn="用户名"/>
<ITEM key="APPCODE" val="1250002" eng="" rmk="百度" fmt="" chn="网络应用代码"/>
<CONDITION rel="BTW">
<ITEM key="START_TIME" val="1321891200" eng="START_TIME" rmk="" fmt="" chn="开始时间"/>
<ITEM key="END_TIME" val="1321977599" eng="END_TIME" rmk="" fmt="" chn="结束时间"/>
</CONDITION>
</CONDITION>
<DATASET name="WA_COMMON_010011" rmk="查询下发要求返回通用信息">
<DATA>
<!--不填DATASET表示查询所有协议数据集-->
<DATASET name="WA_SOURCE_0005">
<DATA>
<!--不填ITEM表示需要返回WA_SOURCE_0005所有字段-->
<ITEM key=" USER_ID " val="abc123" eng=" USER_ID " />
<ITEM key=" USER_NAME " val="小王" eng=" USER_NAME " />
<ITEM key=" PASSWORD " val="" eng=" PASSWORD " />
<ITEM key=" REAL_NAME " val="王晨" eng=" REAL_NAME " />
<ITEM key=" CERTIFICATE_TYPE " val="1" eng=" CERTIFICATE_TYPE " />
<ITEM key=" CERTIFICATE_CODE " val="420114198905240045" eng=" CERTIFICATE_CODE " />
<ITEM key=" SEX " val="女" eng=" SEX " />
<!-- 其他字段 -->
</DATA>
</DATASET>
<DATASET name="WA_BASIC_0009">
<DATA>
<!--不填ITEM表示需要返回WA_BASIC_0009所有字段-->
<ITEM key=" USER_ID " val="abc123" eng=" USER_ID " />
<ITEM key=" USER_NAME " val="小王" eng=" USER_NAME " />
<ITEM key=" CONNECT_USER_ID " val="moon123" eng=" CONNECT_USER_ID " />
<ITEM key="CONNECT_USER_NAME " val="小岑" eng="CONNECT_USER_NAME " />
<!--其他字段 -->
</DATA>
</DATASET>
</DATA>
</DATASET>
<!--多个数据集以多个DATASET表示 -->
</DATA>
</DATASET>
</MESSAGE>
Message.java
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Bobbao
* @version 1.0
* @description:
* @date 2018/04/17/15:54
*/
@XStreamAlias("MESSAGE")
public class Message {
@XStreamImplicit(itemFieldName = "DATASET")
private List<DataSet> dataSet;
@XStreamOmitField
private Map<String, DataSet> dataSetMap;
public Message() {
dataSet = new ArrayList<>();
}
public static void main(String[] args) {
String xml = "<MESSAGE>\n" +
"<DATASET name=\"WA_COMMON_010000\" rmk=\"数据交互通用信息 \">\n" +
"<DATA>\n" +
"<ITEM key=\"CLUE_SRC_SYS\" val=\"010000\" eng=\"FROM\" chn=\"发起节点的标识\" rmk=\"\"/>\n" +
"<ITEM key=\"CLUE_DST_SYS\" val=\"110000\" eng=\"TO\" chn=\"接口服务节点机编号\" rmk=\"\"/>\n" +
"<ITEM key=\"MESSAGE_SEQUENCE\" val=\"010000201103070955330012\" eng=\"MESSAGE_SEQUENCE\" chn=\"消息流水号\" rmk=\"流水号ID\"/>\n" +
"<ITEM key=\"MESSAGE_TYPE\" val=\"140011\" eng=\"MESSAGE_TYPE\" chn=\"消息类型\" rmk=\"通用数据查询请求\"/>\n" +
"<ITEM key=\"BUSINESS_SERVER_TYPE\" val=\"02\" eng=\"BUSINESS_SERVER_TYPE\" chn=\"业务服务类型\" rmk=\"查询业务服务类型(数字)\"/>\n" +
"</DATA>\n" +
"</DATASET>\n" +
"<DATASET name=\"WA_COMMON_010010\" rmk=\"查询下发通用信息\">\n" +
"<DATA>\n" +
"<ITEM key=\"SEARCH_RESULT_MAXNUM\" val=\"2000\" eng=\"SEARCH_RESULT_MAXNUM\" chn=\"最多总返回条数\"/>\n" +
"<ITEM key=\"SEARCH_ALLOW_ASYN\" val=\"NO\" eng=\"SEARCH_ALLOW_ASYN\" chn=\"是否异步\"/>\n" +
"<ITEM key=\"SERVICE_ID\" val=\"S01000011000010001\" rmk=\"回调服务ID\"/>\n" +
"<ITEM key=\"CLUE_ID\" val=\"0100004001201103070955330023\" rmk=\"查询任务标识(异步查询时才需要)\"/>\n" +
"<ITEM key=\"SEARCH_RESULT_COUNT\" val=\"1000\" eng=\"SEARCH_RESULT_COUNT\" chn=\"一次查询返回结果数\"/>\n" +
"<ITEM key=\"SEARCH_STRUCTURED\" val=\"YES\" eng=\"SEARCH_STRUCTURED\" chn=\"是否要结构化数据\"/>\n" +
"<ITEM key=\"SEARCH_CONTEXT\" val=\"YES\" eng=\"SEARCH_CONTEXT\" chn=\"是否要附带摘要数据\"/>\n" +
"<ITEM key=\"SEARCH_DETAILOPTIAN\" val=\"NO\" eng=\"SEARCH_DETAILOPTIAN\" chn=\"是否要附带全文数据\"/>\n" +
"<CONDITION rel=\"AND\">\n" +
"<ITEM key=\"USERNAME\" val=\"12345678\" eng=\"USERNAME\" rmk=\"可同时查出发送方和接收方\" fmt=\"\" chn=\"用户名\"/>\n" +
"<ITEM key=\"APPCODE\" val=\"1250002\" eng=\"\" rmk=\"百度\" fmt=\"\" chn=\"网络应用代码\"/>\n" +
"<CONDITION rel=\"BTW\">\n" +
"<ITEM key=\"START_TIME\" val=\"1321891200\" eng=\"START_TIME\" rmk=\"\" fmt=\"\" chn=\"开始时间\"/>\n" +
"<ITEM key=\"END_TIME\" val=\"1321977599\" eng=\"END_TIME\" rmk=\"\" fmt=\"\" chn=\"结束时间\"/>\n" +
"</CONDITION>\n" +
"</CONDITION>\n" +
"<CONDITION rel=\"OR\">\n" +
"<ITEM key=\"USERNAME\" val=\"12345678\" eng=\"USERNAME\" rmk=\"可同时查出发送方和接收方\" fmt=\"\" chn=\"用户名\"/>\n" +
"<ITEM key=\"APPCODE\" val=\"1250002\" eng=\"\" rmk=\"百度\" fmt=\"\" chn=\"网络应用代码\"/>\n" +
"<CONDITION rel=\"BTW\">\n" +
"<ITEM key=\"START_TIME\" val=\"1321891200\" eng=\"START_TIME\" rmk=\"\" fmt=\"\" chn=\"开始时间\"/>\n" +
"<ITEM key=\"END_TIME\" val=\"1321977599\" eng=\"END_TIME\" rmk=\"\" fmt=\"\" chn=\"结束时间\"/>\n" +
"</CONDITION>\n" +
"</CONDITION>\n" +
"<DATASET name=\"WA_COMMON_010011\" rmk=\"查询下发要求返回通用信息\">\n" +
"<DATA>\n" +
"<DATASET name=\"WA_SOURCE_0005\">\n" +
"<DATA>\n" +
"<ITEM key=\" USER_ID \" val=\"abc123\" eng=\" USER_ID \"/>\n" +
"<ITEM key=\" USER_NAME \" val=\"小王\" eng=\" USER_NAME \"/>\n" +
"<ITEM key=\" PASSWORD \" val=\"\" eng=\" PASSWORD \"/>\n" +
"<ITEM key=\" REAL_NAME \" val=\"王晨\" eng=\" REAL_NAME \"/>\n" +
"<ITEM key=\" CERTIFICATE_TYPE \" val=\"1\" eng=\" CERTIFICATE_TYPE \"/>\n" +
"<ITEM key=\" CERTIFICATE_CODE \" val=\"420114198905240045\" eng=\" CERTIFICATE_CODE \"/>\n" +
"<ITEM key=\" SEX \" val=\"女\" eng=\" SEX \"/>\n" +
"</DATA>\n" +
"</DATASET>\n" +
"<DATASET name=\"WA_BASIC_0009\">\n" +
"<DATA>\n" +
"<ITEM key=\" USER_ID \" val=\"abc123\" eng=\" USER_ID \"/>\n" +
"<ITEM key=\" USER_NAME \" val=\"小王\" eng=\" USER_NAME \"/>\n" +
"<ITEM key=\" CONNECT_USER_ID \" val=\"moon123\" eng=\" CONNECT_USER_ID \"/>\n" +
"<ITEM key=\"CONNECT_USER_NAME \" val=\"小岑\" eng=\"CONNECT_USER_NAME \"/>\n" +
"</DATA>\n" +
"</DATASET>\n" +
"</DATA>\n" +
"</DATASET>\n" +
"</DATA>\n" +
"</DATASET>\n" +
"</MESSAGE>";
XStream xStream = new XStream();
xStream.processAnnotations(Message.class);
Message message = (Message) xStream.fromXML(xml);
message.init();
System.out.println(message);
System.out.println("----------------");
XStream xStream1 = new XStream();
xStream1.processAnnotations(DataSet.class);
System.out.println(xStream1.toXML(message.getDataSetByName("WA_COMMON_010010")));
}
public List<DataSet> getDataSet() {
return dataSet;
}
public void addDataSet(DataSet dataSet) {
this.dataSet.add(dataSet);
}
public void init() {
dataSetMap = new HashMap<>(8);
for (DataSet dataSet : dataSet) {
dataSet.init();
dataSetMap.put(dataSet.getName(), dataSet);
}
}
@Override
public String toString() {
return "Message{" +
"dataSet=" + dataSet +
'}';
}
public DataSet getDataSetByName(String dataSetName) {
return dataSetMap.get(dataSetName);
}
}
DataSet.java
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
/**
* @author Bobbao
* @version 1.0
* @description:
* @date 2018/04/17/16:11
*/
@XStreamAlias("DATASET")
public class DataSet {
@XStreamAlias("name")
@XStreamAsAttribute
private String name;
@XStreamAlias("rmk")
@XStreamAsAttribute
private String rmk;
@XStreamAlias("DATA")
private Data data;
public DataSet(String name, String rmk, Data data) {
this.name = name;
this.rmk = rmk;
this.data = data;
}
public void init(){
data.init();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRmk() {
return rmk;
}
public void setRmk(String rmk) {
this.rmk = rmk;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
@Override
public String toString() {
return "DataSet{" +
"name='" + name + '\'' +
", rmk='" + rmk + '\'' +
", data=" + data +
'}';
}
}
Data.java
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Bobbao
* @version 1.0
* @description:
* @date 2018/04/18/10:59
*/
@XStreamAlias("DATA")
public class Data {
@XStreamImplicit(itemFieldName = "ITEM")
private List<Item> items;
@XStreamImplicit(itemFieldName = "CONDITION")
private List<Condition> conditions;
@XStreamImplicit(itemFieldName = "DATASET")
private List<DataSet> dataSet;
@XStreamOmitField
private Map<String, Item> itemMap;
@XStreamOmitField
private Map<String, Condition> conditionMap;
@XStreamOmitField
private Map<String, DataSet> dataSetMap;
public Data() {
this.items = new ArrayList<>();
this.conditions = new ArrayList<>();
this.dataSet = new ArrayList<>();
}
public void init() {
itemMap = new HashMap<>(8);
conditionMap = new HashMap<>(8);
dataSetMap = new HashMap<>(8);
if (items != null) {
for (Item item : items) {
itemMap.put(item.getKey(), item);
}
}
if (conditions != null) {
for (Condition condition : conditions) {
condition.init();
conditionMap.put(condition.getRel(), condition);
}
}
if (dataSet != null) {
for (DataSet dataSet : dataSet) {
dataSet.init();
dataSetMap.put(dataSet.getName(), dataSet);
}
}
}
public Item getItemByKey(String key) {
return itemMap.get(key);
}
public Condition getConditionByRel(String rel) {
return conditionMap.get(rel);
}
public DataSet getDataSetByName(String name) {
return dataSetMap.get(name);
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
System.out.println("---------------");
this.items = items;
}
public List<Condition> getConditions() {
return conditions;
}
public void setConditions(List<Condition> conditions) {
this.conditions = conditions;
}
public List<DataSet> getDataSet() {
return dataSet;
}
public void setDataSet(List<DataSet> dataSet) {
System.out.println("---------------");
this.dataSet = dataSet;
}
public void addItem(Item item) {
items.add(item);
}
public void addCondition(Condition condition) {
conditions.add(condition);
}
public void addDataSet(DataSet dataSet) {
this.dataSet.add(dataSet);
}
@Override
public String toString() {
return "Data{" +
"items=" + items +
", condition=" + conditions +
", dataSet=" + dataSet +
'}';
}
}
Item.java
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
/**
* @description:
* @version 1.0
* @author Bobbao
* @date 2018/04/17/16:31
*/
@XStreamAlias("ITEM")
public class Item {
@XStreamAlias("key")
@XStreamAsAttribute
private String key;
@XStreamAlias("val")
@XStreamAsAttribute
private String val;
@XStreamAlias("eng")
@XStreamAsAttribute
private String eng;
@XStreamAlias("chn")
@XStreamAsAttribute
private String chn;
@XStreamAlias("rmk")
@XStreamAsAttribute
private String rmk;
@XStreamAlias("fmt")
@XStreamAsAttribute
private String fmt;
public Item(String key, String val, String eng, String chn, String rmk, String fmt) {
this.key = key;
this.val = val;
this.eng = eng;
this.chn = chn;
this.rmk = rmk;
this.fmt = fmt;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public String getEng() {
return eng;
}
public void setEng(String eng) {
this.eng = eng;
}
public String getChn() {
return chn;
}
public void setChn(String chn) {
this.chn = chn;
}
public String getRmk() {
return rmk;
}
public void setRmk(String rmk) {
this.rmk = rmk;
}
public String getFmt() {
return fmt;
}
public void setFmt(String fmt) {
this.fmt = fmt;
}
@Override
public String toString() {
return "Item{" +
"key='" + key + '\'' +
", val='" + val + '\'' +
", eng='" + eng + '\'' +
", chn='" + chn + '\'' +
", rmk='" + rmk + '\'' +
", fmt='" + fmt + '\'' +
'}';
}
}
Condition.java
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Bobbao
* @version 1.0
* @description:
* @date 2018/04/18/14:52
*/
@XStreamAlias("CONDITION")
public class Condition {
@XStreamAlias("rel")
@XStreamAsAttribute
private String rel;
@XStreamImplicit(itemFieldName = "ITEM")
private List<Item> items;
@XStreamImplicit(itemFieldName = "CONDITION")
private List<Condition> conditions;
@XStreamOmitField
private Map<String, Item> itemMap;
@XStreamOmitField
private Map<String, Condition> conditionMap;
public Condition(String rel) {
this.rel = rel;
items = new ArrayList<>();
conditions = new ArrayList<>();
}
public void addItem(Item item) {
items.add(item);
}
public void addCondition(Condition condition) {
conditions.add(condition);
}
public void init() {
itemMap = new HashMap<>();
conditionMap = new HashMap<>();
if (items != null) {
for (Item item : items) {
itemMap.put(item.getKey(), item);
}
}
if (conditions != null) {
for (Condition condition : conditions) {
condition.init();
conditionMap.put(condition.getRel(), condition);
}
}
}
public Item getItemByKey(String key) {
return itemMap.get(key);
}
public Condition getConditionByRel(String rel) {
return conditionMap.get(rel);
}
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public String getRel() {
return rel;
}
public void setRel(String rel) {
this.rel = rel;
}
public Map<String, Item> getItemMap() {
return itemMap;
}
public void setItemMap(Map<String, Item> itemMap) {
this.itemMap = itemMap;
}
public List<Condition> getConditions() {
return conditions;
}
public void setConditions(List<Condition> conditions) {
this.conditions = conditions;
}
@Override
public String toString() {
return "Condition{" +
"rel='" + rel + '\'' +
", items=" + items +
", conditions=" + conditions +
'}';
}
}
xml->Java对象
XStream xStream = new XStream();
xStream.processAnnotations(Message.class);//设置模板
Message message = (Message) xStream.fromXML(xml);
java对象->xml
XStream xStream1 = new XStream();
xStream1.processAnnotations(DataSet.class);
System.out.println(xStream1.toXML(message.getDataSetByName("WA_COMMON_010010")));