(接上一篇文章:微信公众平台开发之处理普通消息---1)
本章节主要讲述对普通消息的处理。
当用户关注微信公众号时,取消关注时,给公众号发各种信息时,作出简单的响应(处理)。
一、在com.cc.wechat.util包下新建工具类:
---MessageUtil:
对xml解析需要用到两个工具包:
package com.cc.wechat.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 对xml文件进行解析
* 对各种消息进行回复
* @author ICHN
*
*/
public class MessageUtil {
/**
* 请求和响应
*/
//请求内容为:文本
public static final String REQ_MSG_TYPE_TEXT = "text";
//请求内容为:图片
public static final String REQ_MSG_TYPE_IMG = "image";
//请求内容为:语音
public static final String REQ_MSG_TYPE_VOICE = "voice";
//请求内容为:链接
public static final String REQ_MSG_TYPE_LINK = "link";
//请求内容为:位置
public static final String REQ_MSG_TYPE_LOCATION = "location";
//推送
public static final String REQ_MSG_TYPE_EVENT = "event";
//响应内容为:文本
public static final String RESP_MSG_TYPE_TEXT = "text";
//响应内容为:图文
public static final String RESP_MSG_TYPE_NEWS = "news";
//响应内容为:语音
public static final String RESP_MSG_TYPE_VOICE = "voice";
//响应内容为:音乐
public static final String RESP_MSG_TYPE_MUSIC = "music";
/**
* 事件
*/
//订阅公众号(有人关注时给出的相应内容)
public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
//取消订阅
public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
/**
* 解析服务器端发回的xml(微信服务器端)
*/
public static Map<String, String> parseXML(HttpServletRequest req) {
//详细解析过程单独写在下面
}
/**
* 递归解析xml
* @param map
* @param root
* @return
*/
public static Map<String, String> recursiveParseXML(Map<String, String> map, Element root) {
//详细解析过程单独写在下面
}
/**
* 扩展xstream,使其支持CDATA块
*/
private static XStream xstream = new XStream(new XppDriver() {
//详细解析过程单独写在下面
}
/**
* 返回的内容也为xml文件
* 所以要对响应的类进行转换
* 重载方式回显xml
*/
//响应文本内容
public static String MessageToXml(TextMessage textMessage) {
xstream.alias("xml", textMessage.getClass());
return xstream.toXML(textMessage);
}
//响应语音内容
public static String MessageToXml(VoiceMessage voiceMessage) {
xstream.alias("xml", voiceMessage.getClass());
return xstream.toXML(voiceMessage);
}
//响应图文内容
public static String MessageToXml(NewsMessage newsMessage) {
xstream.alias("xml", newsMessage.getClass());
xstream.alias("item", new Article().getClass());
return xstream.toXML(newsMessage);
}
//......其他响应内容同上........
}xml文件解析过程:
public static Map<String, String> parseXML(HttpServletRequest req) {
//用一个Map来存放已解析的xml文件
Map<String, String> map = new HashMap<String, String>();
try {
//读取请求内容
InputStream is = req.getInputStream();
//开始解析
SAXReader sr = new SAXReader();
//文件
Document document = sr.read(is);
//从xml根部开始解析
Element root = document.getRootElement();
//递归map,直到所有的xml内容均存放到map中
map = recursiveParseXML(map, root);
//关闭输入流,释放资源
is.close();
is = null;
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
return map;
}
//递归解析xml
public static Map<String, String> recursiveParseXML(Map<String, String> map, Element root) {
//从根节点开始读取
if(null != root) {
List<Element> elementsList = root.elements();
//如果就是叶子节点
if(0 == elementsList.size()) {
//存放到map中
map.put(root.getName(), root.getText());
}else {
//非子节点,则遍历所有节点
for(Element element : elementsList) {
recursiveParseXML(map, element);
}
}
}
return map;
}扩展xstream,使其支持CDATA块:
private static XStream xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
// 对所有xml节点的转换都增加CDATA标记
boolean cdata = true;
@SuppressWarnings("unchecked")
public void startNode(String name, Class clazz) {
super.startNode(name, clazz);
}
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});二、在com.cc.wechat.util包下新建信息处理核心类,专门负责接收微信服务器端发来的请求和作出相应的处理、回复:
---CoreService:
package com.cc.wechat.service;
import java.util.Date;
import java.util.Map;
import com.cc.wechat.message.TextMessage;
import com.cc.wechat.util.MessageUtil;
/**
* 专门负责接收微信服务器端发来的请求和作出相应的处理、回复
* 核心服务
* @author ICHN
*
*/
public class CoreService {
public static String processRequest(Map<String, String> requestMap) {
//要响应的内容
String respMessage = null;
/*****************************************************/
//默认返回的内容
String respContent = "出现意外...";
//用户微信账号open_id
String fromUserName = requestMap.get("FromUserName");
//开发者公众号
String toUserName = requestMap.get("ToUserName");
//接收到的信息类型
String msgType = requestMap.get("MsgType");
/****************************************************/
//首先对接收到的消息类型以文本回复的方式进行处理
TextMessage textMessage = new TextMessage();
//此处容易混淆,注意区分
textMessage.setToUserName(fromUserName);
textMessage.setFromUserName(toUserName);
textMessage.setCreateTime(new Date().getTime());
textMessage.setMsgType(MessageUtil.REQ_MSG_TYPE_TEXT);
textMessage.setContent("你发送的是文本消息");
respMessage = MessageUtil.MessageToXml(textMessage);
return respMessage;
}
}三、修改CoreServlet中的doPost:
/**
* 接收微信服务器请求处理的内容
* 交给CoreService类处理
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置字符集 微信默认的为UTF-8
//请求
request.setCharacterEncoding("utf-8");
//响应
response.setCharacterEncoding("utf-8");
try{
//定义一个Map来接收请求的xml文件
Map<String, String> requestMap = null;
//响应回去的xml文件
String responseXml = null;
//处理接收到的消息
requestMap = MessageUtil.parseXML(request);
responseXml = CoreService.processRequest(requestMap);
}
//向服务器相关响应信息
PrintWriter out = response.getWriter();
out.print(responseXml);
out.close();
}catch(Exception e) {
e.printStackTrace();
}
}四、重启tomcat,向公众号发送数字“1”进行测试,效果如下图:
本文出自 “顽强的石头” 博客,请务必保留此出处http://chn0515.blog.51cto.com/10646281/1688187
原文地址:http://chn0515.blog.51cto.com/10646281/1688187