在接口通信的实际开发中经常会碰到使用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; } }