xstream 初学笔记
简介:本章主要写的是,在微信开发中,有发送xml数据,其中用到了xstream这个框架进行javaBean和xml数据的转换,但是在每个标签中,微信需要的接口都需要封装上一个<![CDATA[fromUser]]>东西,所以使用了其中的解析器来,在本章中用到了xpp这个解析类,别的我还没有搞明白,但是xstream框架很丰富,此处指给出一个特例,把JavaBean中的其余属性封装上特殊标签,CreateTime不需要,由此给出了下面的程序.
需要下载xstream-1.3.1.jar包
关于xstream的别的功能以及注解,网上很多,再次不多做解释.
第一种方法
package org.liufeng.course.message.resp; /** * 文本消息 * * @author liufeng * @date 2013-05-19 */ public class TextMessage extends BaseMessage { // 回复的消息内容 private String Content; public String getContent() { return Content; } public void setContent(String content) { Content = content; } }
package org.liufeng.course.message.resp; /** * 消息基类(公众帐号 -> 普通用户) * * @author liufeng * @date 2013-05-19 */ public class BaseMessage { // 接收方帐号(收到的OpenID) private String ToUserName; // 开发者微信号 private String FromUserName; // 消息创建时间 (整型) private long CreateTime; // 消息类型(text/music/news) private String MsgType; // 位0x0001被标志时,星标刚收到的消息 private int FuncFlag; public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public long getCreateTime() { return CreateTime; } public void setCreateTime(long createTime) { CreateTime = createTime; } public String getMsgType() { return MsgType; } public void setMsgType(String msgType) { MsgType = msgType; } public int getFuncFlag() { return FuncFlag; } public void setFuncFlag(int funcFlag) { FuncFlag = funcFlag; } }
package org.liufeng.course.util; import java.io.InputStream; import java.io.Writer; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.liufeng.course.message.resp.Article; import org.liufeng.course.message.resp.MusicMessage; import org.liufeng.course.message.resp.NewsMessage; import org.liufeng.course.message.resp.TextMessage; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XppDriver; /** * 消息工具类 */ public class MessageUtil { /** * 返回消息类型:文本 */ public static final String RESP_MESSAGE_TYPE_TEXT = "text"; /** * 文本消息对象转换成xml * alias 起别名,如果没有,根节点将面为com.pacage.textMessage的形式 * @param textMessage 文本消息对象 * @return xml */ public static String textMessageToXml(TextMessage textMessage) { xstream.alias("xml",textMessage.getClass()); return xstream.toXML(textMessage); } public static void main(String[] args) { TextMessage textMessage = new TextMessage(); textMessage.setToUserName("fromUser"); textMessage.setFromUserName("toUser"); textMessage.setCreateTime(new Date().getTime()); textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT); textMessage.setFuncFlag(0); String xml = new MessageUtil().textMessageToXml(textMessage); System.out.println(xml); } /** * 扩展xstream,使其支持CDATA块 */ private static XStream xstream = new XStream(new XppDriver() { public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; String createTime = ""; @SuppressWarnings("unchecked") public void startNode(String name,Class clazz) { if(name!=null&&name.equals("CreateTime")){ createTime = "CreateTime"; }else{ createTime=name; } super.startNode(name,clazz); } protected void writeText(QuickWriter writer,String text) { if (cdata&&!createTime.equals("CreateTime")) { writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } else { writer.write(text); } } }; } }); }
第二种方法(注解)
package com.xml.date.CDATA; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD}) public @interface XStreamCDATA { }
package com.xml.date.CDATA; import com.thoughtworks.xstream.annotations.XStreamAlias; public class TextMessageDto { @XStreamAlias("ToUserName") @XStreamCDATA private String ToUserName; @XStreamAlias("FromUserName") @XStreamCDATA private String FromUserName; private long CreateTime; private String MsgType; private int FuncFlag; public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public long getCreateTime() { return CreateTime; } public void setCreateTime(long createTime) { CreateTime = createTime; } public String getMsgType() { return MsgType; } public void setMsgType(String msgType) { MsgType = msgType; } public int getFuncFlag() { return FuncFlag; } public void setFuncFlag(int funcFlag) { FuncFlag = funcFlag; } }
package com.xml.date.CDATA; import java.io.Writer; import java.lang.reflect.Field; import java.util.Date; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XppDriver; /** * 消息工具类 * @author 高国藩 * @date 2015年8月6日 上午9:38:53 * */ public class MessageUtil { private static XStream xstream = createXstream(); public static XStream createXstream() { return new XStream(new XppDriver() { @Override public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { boolean cdata = false; Class<?> targetClass = null; @Override public void startNode(String name,@SuppressWarnings("rawtypes") Class clazz) { super.startNode(name,clazz); //业务处理,对于用XStreamCDATA标记的Field,需要加上CDATA标签 if(!name.equals("xml")){ cdata = needCDATA(targetClass,name); }else{ targetClass = clazz; } } @Override protected void writeText(QuickWriter writer,String text) { if (cdata) { writer.write(cDATA(text)); } else { writer.write(text); } } }; } }); } private static String cDATA(String text){ return "<![CDATA["+text+"]]>"; } private static boolean needCDATA(Class<?> targetClass,String fieldAlias){ boolean cdata = false; //first,scan self cdata = existsCDATA(targetClass,fieldAlias); if(cdata) return cdata; //if cdata is false,scan supperClass until java.lang.Object Class<?> superClass = targetClass.getSuperclass(); while(!superClass.equals(Object.class)){ cdata = existsCDATA(superClass,fieldAlias); if(cdata) return cdata; superClass = superClass.getClass().getSuperclass(); } return false; } private static boolean existsCDATA(Class<?> clazz,String fieldAlias){ //scan fields Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { //1. exists XStreamCDATA if(field.getAnnotation(XStreamCDATA.class) != null ){ XStreamAlias xStreamAlias = field.getAnnotation(XStreamAlias.class); //2. exists XStreamAlias if(null != xStreamAlias){ if(fieldAlias.equals(xStreamAlias.value()))//matched return true; }else{// not exists XStreamAlias if(fieldAlias.equals(field.getName())) return true; } } } return false; } /** * 文本消息对象转换成xml * alias 起别名,根节点将面为com.pacage.textMessage的形式 * @param textMessage 文本消息对象 * @return xml */ public static String textMessageToXml(TextMessageDto textMessage) { xstream.alias("xml",textMessage.getClass()); return xstream.toXML(textMessage); } public static void main(String[] args) { TextMessageDto textMessage = new TextMessageDto(); textMessage.setCreateTime(new Date().getTime()); textMessage.setFromUserName("来源"); textMessage.setToUserName("取出"); textMessage.setFuncFlag(0); textMessage.setMsgType("news"); String str = MessageUtil.textMessageToXml(textMessage); System.out.println(str); } }
<xml> <ToUserName><![CDATA[取出]]></ToUserName> <FromUserName><![CDATA[来源]]></FromUserName> <CreateTime>1442486285083</CreateTime> <MsgType>news</MsgType> <FuncFlag>0</FuncFlag> </xml>