XML序列化及反序列化
最近在做微信支付对接,微信接口是XML格式的,字段名如同appid,sign_type等.要将XML字段与JAVA 类字段对应起来.将遇到的问题及解决方法总结下.
本人采用XStream操作.
1.@XStreamAlias("name")--即可重命名为想的名称.
此注解可以加在字段或类上,当加到类上时,即重命名类对应的节点名称.
例如:
1 @XStreamAlias("xml") 2 public class WxUnifyOrderParameter { 3 /** 4 * 公众账号ID 5 */ 6 @XStreamAlias("appid") 7 @MapKeyAlias("appid") 8 private String appId; 9 /** 10 * 商户号 11 */ 12 @MapKeyAlias("mch_id") 13 @XStreamAlias("mch_id") 14 private String mchId; 15 } 16 WxUnifyOrderParameter para=new WxUnifyOrderParameter(); 17 para.setAppId("app1"); 18 para.setMchId("mchId1"); 19 XStream xs=new XStream(); 20 xs.autodetectAnnotations(Boolean.TRUE);//设置自动检测注解 21 xs.toXML(para)
得到的 XML如同<xml><appid>app1</appid><mch__id>mchId1</mch__id></xml>
仔佃看上面的 XML 片段,发现下滑线是两根.引出问题2
2.new XStream(new Xpp3Driver(new NoNameCoder()))使用 NoNameCoder 解决.
示例:略
3.添加 CDATA
1 xStreamToXml=new XStream(new Xpp3Driver(new NoNameCoder()) { 2 private static final String CDATA_START="<![CDATA["; 3 private static final String CDATA_END="]]>"; 4 @Override 5 public HierarchicalStreamWriter createWriter(Writer out) { 6 return new PrettyPrintWriter(out,getNameCoder()) { 7 //此处注意:记得调用new PrettyPrintWriter(out,getNameCoder()), 8 //若调用new PrettyPrintWriter(out),则字段名会编码,双下下滑线问题又会出现. 9 // 对所有xml节点的转换都增加CDATA标记 10 boolean cdata = true; 11 12 @Override 13 @SuppressWarnings("rawtypes") 14 public void startNode(String name, Class clazz) { 15 super.startNode(name, clazz); 16 } 17 18 @Override 19 protected void writeText(QuickWriter writer, String text) { 20 if (cdata) { 21 writer.write(CDATA_START); 22 writer.write(text); 23 writer.write(CDATA_END); 24 } else { 25 writer.write(text); 26 } 27 } 28 }; 29 } 30 });
输出结果类似如下:
<xml><body><![CDATA[测试公众号支付]]></body>
<out_trade_no><![CDATA[WTWTEST1508226319186]]></out_trade_no>
<total_fee><![CDATA[10]]></total_fee>
<spbill_create_ip><![CDATA[10.10.50.54]]></spbill_create_ip></xml>
4.xStreaml.alias("xml",WxUnifyOrderParameter.class);
利用方法设置别名,主要用途,当WxUnifyOrderParameter与WxUnifyOrderResult两个类都采用@XStreamAlias("xml")时,反序列化时有可能找错目标类.我们可以这么处理,构造两个 XStream 对象,去除类上的@XStreamAlias("xml")注解.然后调用
xStreamlPara.alias("xml",WxUnifyOrderParameter.class);
xStreamlResult.alias("xml",WxUnifyOrderResult.class);
反序列化时采用对应的对象调用.