(接上一篇文章:微信公众平台开发之处理普通消息---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”进行测试,效果如下图:
时间: 2024-10-07 03:45:22