在接口通信的实际开发中经常会碰到使用XML格式进行两个系统间的交互。通信的客户端使用的方法有很多。
一、使用JAXB或XStream将Java对象与XML进行互转,例子使用XStream:
Maven依赖:
<dependency> <groupId>com.thoughtworks.xstream</groupId> <artifactId>xstream</artifactId> <version>1.4.7</version> </dependency>
POJO对象1:
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
@XStreamAlias("request")
public class TradeFlow {
@XStreamAlias("seriId")
private String seriId = "1";
@XStreamAlias("parterId")
private String parterId = "2";
@XStreamAlias("pointSize")
private String pointSize = "3";
@XStreamAlias("unitId")
private String unitId = "4";
@XStreamAlias("validateStr")
private String validateStr = "5";
@XStreamAlias("phones")
private List<Phone> phones;
@XStreamAlias("telPhones")
private List<String> telPhones;
@XStreamImplicit(itemFieldName = "telphone2")
private List<String> telPhones2;
//省略所有属性的get/set方法
}
POJO对象2:
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("phone")
public class Phone {
@XStreamAlias("msisdn")
private String msisdn;
//省略所有属性的get/set方法
}
测试方法:
public static void main(String[] args) {
TradeFlow tradeFlow = new TradeFlow();
XStream xstream = new XStream();
xstream.processAnnotations(TradeFlow.class);
List<Phone> array = new ArrayList<Phone>();
Phone phone = new Phone();
phone.setMsisdn("13000000000");
array.add(phone);
tradeFlow.setPhones(array);
List<String> telArray = new ArrayList<String>();
telArray.add("0571-88000000");
telArray.add("0571-88111111");
tradeFlow.setTelPhones(telArray);
tradeFlow.setTelPhones2(telArray);
System.out.println(xstream.toXML(tradeFlow));
String xml = xstream.toXML(tradeFlow);//对象转换XML字符串
TradeFlow test = (TradeFlow)xstream.fromXML(xml);//XML字符串转换对象
System.out.println(test.getParterId());
}
结果如下:
<request>
<seriId>1</seriId>
<parterId>2</parterId>
<pointSize>3</pointSize>
<unitId>4</unitId>
<validateStr>5</validateStr>
<phones>
<phone>
<msisdn>13000000000</msisdn>
</phone>
</phones>
<telPhones>
<string>0571-88000000</string>
<string>0571-88111111</string>
</telPhones>
<telphone2>0571-88000000</telphone2>
<telphone2>0571-88111111</telphone2>
</request>
注意:
1.下划线"_"在xstream中比较特殊,是作为转义字符,所以建议在实际应用中建议不要使用下划线作为xml中的节点名称。
解决方案网上搜索了具体如下:http://www.iteye.com/problems/94338
2.POJO对象中若参数值为NULL,则xstream渲染时会自动过滤掉该节点。所以如果需要显示该节点,必须赋予相应的空值(例如:初始化一个空数组、空字符串)。
JAXB与XStream之间的比较:http://www.blogjava.net/ldd600/archive/2009/03/04/257832.html
其他注解使用参看资料:
http://liuzidong.iteye.com/blog/1059861
http://www.cnblogs.com/hoojo/archive/2011/04/22/2025197.html
二、使用jdom读取xml文件或字符串,然后对节点进行操作:
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Xml2StrReader {
private static Map<String, String> xmlStr = new HashMap<String, String>(10);
private Xml2StrReader(){}
/**
* 默认路径为:classpath:webservice/
*/
private static String xmlStr(String fileName) throws Exception{
SAXReader reader = new SAXReader();//取得dom4j的解析器
Resource res = new ClassPathResource("webservice/"+fileName);
Document document = reader.read(res.getInputStream());
String text = document.asXML();
return text;
}
/**
* 利用HashMap.put若存在则调用get方法的特性
* 保证存储到内存时不抛错,大不了获取的时候出现并发就多解析一次,不考虑并发情况
*/
public static String getXmlStrFactory(String fileName) throws Exception{
if(xmlStr.containsKey(fileName))
return xmlStr.get(fileName);
String str = xmlStr(fileName);
xmlStr.put(fileName, str);
return str;
}
}