版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_32953079/article/details/82848054
微信公众号开发最主要的一个问题就是解决自己服务器和微信服务器之间的数据交互,因为之前的时候微信公众号都是采用的xml格式,而现在新的API都是采用json了,而我是开发的个人订阅号,所以需要解决xml与bean相互转换的问题。
纵观目前百度上的xml与java对象的转换工具,主要是JAXB,XStream,DOM4j等等,我看了看例子,感觉XStream比较简单上手,再加上之前有在老师的公司看到过XStream,当时也是开发微信公众号,所以决定采用XStream
微信公众号的数据格式如下:
<xml>
<ToUserName>< ![CDATA[toUser] ]></ToUserName>
<FromUserName>< ![CDATA[fromUser] ]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType>< ![CDATA[text] ]></MsgType>
<Content>< ![CDATA[你好] ]></Content>
</xml>
可以看到,给微信服务器发送数据的时候是这个xml格式,所以我们需要使用XStream来根据bean的属性来动态构造出这样的数据结构,首先导入XStream的jar包;
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
配置一下XStream在根据bean属性生成xml的时候自动加上 ---![CDATA[----和----]]---,如下配置:
//xstream扩展,bean转xml自动加上![CDATA[]]
public static XStream getMyXStream() {
return new XStream(new XppDriver() {
@Override
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
// 对所有xml节点都增加CDATA标记
boolean cdata = true;
@Override
public void startNode(String name, Class clazz) {
super.startNode(name, clazz);
}
@Override
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});
}
写个测试方法看看 :
/**
* bean转成微信的xml消息格式
* @param object
* @return
*/
public static String beanToXml( Object object) {
XStream xStream = getMyXStream();
xStream.alias("xml", object.getClass());
xStream.processAnnotations(object.getClass());
String xml = xStream.toXML(object);
if (!StringUtils.isEmpty(xml)){
return xml;
}else{
return null;
}
}
新建个实体;
public class MessageTextEntity {
@XStreamAlias("ToUserName")
private String toUserName;
@XStreamAlias("FromUserName")
private String fromUserName;
//由于微信服务端需要的时间整形是以秒为单位的,故需要除以1000L
// this.setCreateTime(String.valueOf(System.currentTimeMillis() / 1000L));
@XStreamAlias("CreateTime")
private String createTime;
@XStreamAlias("MsgType")
private String msgType;
@XStreamAlias("Content")
private String content;
public MessageTextEntity() {
}
@Override
public String toString() {
return "MessageTextEntity{" +
"toUserName='" + toUserName + '\'' +
", fromUserName='" + fromUserName + '\'' +
", createTime='" + createTime + '\'' +
", msgType='" + msgType + '\'' +
", content='" + content + '\'' +
'}';
}
public String getToUserName() {
return toUserName;
}
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getFromUserName() {
return fromUserName;
}
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
这里说一下,XStream吧java对象转成xml,在java对象中其实并不需要写getter和setter和默认构造函数的,我这里写了只是习惯而已。
@Test
public void testBeanToXml(){
MessageTextEntity entity = new MessageTextEntity();
entity.setContent("content");
entity.setCreateTime(new Date().toString());
entity.setFromUserName("fromusername");
entity.setMsgType("type");
entity.setToUserName("tousername");
System.out.println(WeChatUtil.beanToXml(entity));
}
运行测试用例,可以看到如下输出
<xml>
<ToUserName><![CDATA[tousername]]></ToUserName>
<FromUserName><![CDATA[fromusername]]></FromUserName>
<CreateTime><![CDATA[Wed Sep 26 08:32:29 CST 2018]]></CreateTime>
<MsgType><![CDATA[type]]></MsgType>
<Content><![CDATA[content]]></Content>
</xml>
这样就OK了,吧xml转成bean的方法就比较简单一点了,
/**
* xml转成bean泛型方法
* @param resultXml
* @param clazz
* @param <T>
* @return
*/
public static <T> T xmlToBean(String resultXml, Class clazz) {
// XStream对象设置默认安全防护,同时设置允许的类
XStream stream = new XStream(new DomDriver());
// XStream.setupDefaultSecurity(stream);
// stream.allowTypes(new Class[]{clazz});
stream.processAnnotations(new Class[]{clazz});
// stream.setMode(XStream.NO_REFERENCES);
stream.alias("xml", clazz);
return (T) stream.fromXML(resultXml);
}
这样就能完成xml到bean的转换了,但是这样直接执行的话会报一个红色的警告信息
Security framework of XStream not initialized, XStream is probably vulnerable.
这是因为要为XStream进行安全设置。吧上面代码注释去掉就可以了。
测试一下:
@Test
public void testXmlToBean(){
String xml = "<xml>" +
"<ToUserName><![CDATA[tousername]]></ToUserName>" +
"<FromUserName><![CDATA[fromusername]]></FromUserName>" +
"<CreateTime>Tue Sep 25 15:10:09 CST 2018</CreateTime>" +
"<MsgType><![CDATA[type]]></MsgType>" +
"<Content><![CDATA[content]]></Content>" + "</xml>";
MessageTextEntity entity = WeChatUtil.xmlToBean(xml, MessageTextEntity.class);
System.out.println(entity);
}
可以看到如下输出:
MessageTextEntity{toUserName='tousername', fromUserName='fromusername', createTime='Tue Sep 25 15:10:09 CST 2018', msgType='type', content='content'}
可以了,现在可以开始微信开发了。