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>