温馨提示:
这篇文章是依赖前几篇的文章的。
第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备
第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发
第三篇 :微信公众平台开发实战之请求消息,响应消息以及事件消息类的封装
首先,我们看看原来写的dopost方法:
/** * 处理微信服务器发来的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO 消息的接收、处理、响应 }
doPost方法有两个参数:
1.request中封装了请求相关的所有内容,可以从request中取出微信服务器发来的消息;
2.response我们可以对接收到的消息进行响应,即发送消息。
一、解析微信服务器传来的消息
因为微信服务器发送过来的是开源框架dom4j去解析
所用到的jar 包是:dom4j-1.6.1.jar
官网下载地址:http://www.dom4j.org/dom4j-1.6.1/
网盘下载地址:http://yunpan.cn/cQyR8KkIXxHXn 访问密码 0f2e
二、将响应消息转换成
如何将响应消息转换成采用开源框架xstream来实现Java类到
所用到的jar包为:xstream-1.3.1.jar
网盘下载地址:http://yunpan.cn/cQyBU2vTYAe2f 访问密码 ad36
封装消息处理工具:
package com.souvc.weixin.util;import java.io.InputStream;import java.io.Writer;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 com.souvc.weixin.message.resp.Article;import com.souvc.weixin.message.resp.ImageMessage;import com.souvc.weixin.message.resp.MusicMessage;import com.souvc.weixin.message.resp.NewsMessage;import com.souvc.weixin.message.resp.TextMessage;import com.souvc.weixin.message.resp.VideoMessage;import com.souvc.weixin.message.resp.VoiceMessage;import com.thoughtworks.xstream.XStream;import com.thoughtworks.xstream.core.util.QuickWriter;import com.thoughtworks.xstream.io.HierarchicalStreamWriter;import com.thoughtworks.xstream.io.import com.thoughtworks.xstream.io./*** 类名: MessageUtil </br>* 描述: 消息处理工具类</br>* 开发人员: souvc </br>* 创建时间: 2015-9-30 </br>* 发布版本:V1.0 </br> */public class MessageUtil { // 请求消息类型:文本 public static final String REQ_MESSAGE_TYPE_TEXT = "text"; // 请求消息类型:图片 public static final String REQ_MESSAGE_TYPE_IMAGE = "image"; // 请求消息类型:语音 public static final String REQ_MESSAGE_TYPE_VOICE = "voice"; // 请求消息类型:视频 public static final String REQ_MESSAGE_TYPE_VIDEO = "video"; // 请求消息类型:小视频 public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo"; // 请求消息类型:地理位置 public static final String REQ_MESSAGE_TYPE_LOCATION = "location"; // 请求消息类型:链接 public static final String REQ_MESSAGE_TYPE_LINK = "link"; // 请求消息类型:事件推送 public static final String REQ_MESSAGE_TYPE_EVENT = "event"; // 事件类型:subscribe(订阅) public static final String EVENT_TYPE_SUBSCRIBE = "subscribe"; // 事件类型:unsubscribe(取消订阅) public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe"; // 事件类型:scan(用户已关注时的扫描带参数二维码) public static final String EVENT_TYPE_SCAN = "scan"; // 事件类型:LOCATION(上报地理位置) public static final String EVENT_TYPE_LOCATION = "LOCATION"; // 事件类型:CLICK(自定义菜单) public static final String EVENT_TYPE_CLICK = "CLICK"; // 响应消息类型:文本 public static final String RESP_MESSAGE_TYPE_TEXT = "text"; // 响应消息类型:图片 public static final String RESP_MESSAGE_TYPE_IMAGE = "image"; // 响应消息类型:语音 public static final String RESP_MESSAGE_TYPE_VOICE = "voice"; // 响应消息类型:视频 public static final String RESP_MESSAGE_TYPE_VIDEO = "video"; // 响应消息类型:音乐 public static final String RESP_MESSAGE_TYPE_MUSIC = "music"; // 响应消息类型:图文 public static final String RESP_MESSAGE_TYPE_NEWS = "news"; /** * 解析微信发来的请求(@param request * @return Map<String, String> * @throws Exception */ @SuppressWarnings("unchecked") public static Map<String, String> parsethrows Exception { // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 释放资源 inputStream.close(); inputStream = null; return map; } /** * 扩展xstream使其支持CDATA */ private static XStream xstream = new XStream(new XppDriver() { public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有 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); } } }; } }); /** * 文本消息对象转换成@param textMessage 文本消息对象 * @return */ public static String messageTo", textMessage.getClass()); return xstream.to/** * 图片消息对象转换成@param imageMessage 图片消息对象 * @return */ public static String messageTo", imageMessage.getClass()); return xstream.to/** * 语音消息对象转换成@param voiceMessage 语音消息对象 * @return */ public static String messageTo", voiceMessage.getClass()); return xstream.to/** * 视频消息对象转换成@param videoMessage 视频消息对象 * @return */ public static String messageTo", videoMessage.getClass()); return xstream.to/** * 音乐消息对象转换成@param musicMessage 音乐消息对象 * @return */ public static String messageTo", musicMessage.getClass()); return xstream.to/** * 图文消息对象转换成@param newsMessage 图文消息对象 * @return */ public static String messageTo", newsMessage.getClass()); xstream.alias("item", new Article().getClass()); return xstream.to
使用CoreServlet 类完成消息的接受与响应:
package com.souvc.weixin.servlet;import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import com.souvc.weixin.service.CoreService;import com.souvc.weixin.util.SignUtil;/** * 类名: CoreServlet </br> * 描述: 来接收微信服务器传来信息 </br> * 开发人员: souvc</br> * 创建时间:2015-9-29 </br> * 发布版本:V1.0 </br> */public class CoreServlet extends HttpServlet { private static final long serialVersionUID = 4323197796926899691L; /** * 确认请求来自微信服务器 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 微信加密签名 String signature = request.getParameter("signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echostr = request.getParameter("echostr"); PrintWriter out = response.getWriter(); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (SignUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); } out.close(); out = null; } /** * 处理微信服务器发来的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 消息的接收、处理、响应 // 将请求、响应的编码均设置为UTF-8(防止中文乱码) request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); // 调用核心业务类接收消息、处理消息 String resp CoreService.processRequest(request); // 响应消息 PrintWriter out = response.getWriter(); out.print(resp
使用CoreService类完成消息的处理:
package com.souvc.weixin.service;import java.util.Date;import java.util.Map;import javax.servlet.http.HttpServletRequest;import com.souvc.weixin.message.resp.TextMessage;import com.souvc.weixin.util.MessageUtil;/*** 类名: CoreService </br>* 描述: 核心服务类 </br>* 开发人员: souvc </br>* 创建时间: 2015-9-30 </br>* 发布版本:V1.0 </br> */public class CoreService { /** * 处理微信发来的请求 * @param request * @return */ public static String processRequest(HttpServletRequest request) { // String respnull; // 默认返回的文本消息内容 String respContent = "未知的消息类型!"; try { // 调用parse Map<String, String> requestMap = MessageUtil.parse// 发送方帐号 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.RESP_MESSAGE_TYPE_TEXT); // 文本消息 if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { respContent = "您发送的是文本消息!"; } // 图片消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) { respContent = "您发送的是图片消息!"; } // 语音消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) { respContent = "您发送的是语音消息!"; } // 视频消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)) { respContent = "您发送的是视频消息!"; } // 视频消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_SHORTVIDEO)) { respContent = "您发送的是小视频消息!"; } // 地理位置消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) { respContent = "您发送的是地理位置消息!"; } // 链接消息 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) { respContent = "您发送的是链接消息!"; } // 事件推送 else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) { // 事件类型 String eventType = requestMap.get("Event"); // 关注 if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { respContent = "谢谢您的关注!"; } // 取消关注 else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) { // TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复 } // 扫描带参数二维码 else if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) { // TODO 处理扫描带参数二维码事件 } // 上报地理位置 else if (eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)) { // TODO 处理上报地理位置事件 } // 自定义菜单 else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) { // TODO 处理菜单点击事件 } } // 设置文本消息的内容 textMessage.setContent(respContent); // 将文本消息对象转换成 resp MessageUtil.messageTocatch (Exception e) { e.printStackTrace(); } return resp
然后部署到我们的BAE上面,体验一下。(部署方法请参照 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发)。
效果如下:
原标题:第四篇 :微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理
关键词:JAVA