首页 > 学院 > 开发设计 > 正文

第四篇:微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理

2019-11-14 15:31:54
字体:
来源:转载
供稿:网友

温馨提示:

     这篇文章是依赖前几篇的文章的。

     第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备

     第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发

     第三篇 :微信公众平台开发实战之请求消息,响应消息以及事件消息类的封装

 

 

首先,我们看看原来写的dopost方法:

 

/**     * 处理微信服务器发来的消息     */    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // TODO 消息的接收、处理、响应    }

 

doPost方法有两个参数:

   1.request中封装了请求相关的所有内容,可以从request中取出微信服务器发来的消息;

   2.response我们可以对接收到的消息进行响应,即发送消息。

 

一、解析微信服务器传来的消息

因为微信服务器发送过来的是xml格式的消息,所以我们可以采用 开源框架dom4j去解析xml 。

所用到的jar 包是:dom4j-1.6.1.jar  

官网下载地址:http://www.dom4j.org/dom4j-1.6.1/

网盘下载地址:http://yunpan.cn/cQyR8KkIXxHXn  访问密码 0f2e

 

二、将响应消息转换成xml返回给微信服务器

 

如何将响应消息转换成xml返回的问题,这里我们将  采用开源框架xstream来实现java类到xml的转换

所用到的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.xml.PRettyPrintWriter;import com.thoughtworks.xstream.io.xml.XppDriver;/*** 类名: 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";    /**     * 解析微信发来的请求(XML)     *      * @param request     * @return Map<String, String>     * @throws Exception     */    @SuppressWarnings("unchecked")    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {        // 将解析结果存储在HashMap中        Map<String, String> map = new HashMap<String, String>();        // 从request中取得输入流        InputStream inputStream = request.getInputStream();        // 读取输入流        SAXReader reader = new SAXReader();        Document document = reader.read(inputStream);        // 得到xml根元素        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) {                // 对所有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);                    }                }            };        }    });    /**     * 文本消息对象转换成xml     *      * @param textMessage 文本消息对象     * @return xml     */    public static String messageToXml(TextMessage textMessage) {        xstream.alias("xml", textMessage.getClass());        return xstream.toXML(textMessage);    }    /**     * 图片消息对象转换成xml     *      * @param imageMessage 图片消息对象     * @return xml     */    public static String messageToXml(ImageMessage imageMessage) {        xstream.alias("xml", imageMessage.getClass());        return xstream.toXML(imageMessage);    }    /**     * 语音消息对象转换成xml     *      * @param voiceMessage 语音消息对象     * @return xml     */    public static String messageToXml(VoiceMessage voiceMessage) {        xstream.alias("xml", voiceMessage.getClass());        return xstream.toXML(voiceMessage);    }    /**     * 视频消息对象转换成xml     *      * @param videoMessage 视频消息对象     * @return xml     */    public static String messageToXml(VideoMessage videoMessage) {        xstream.alias("xml", videoMessage.getClass());        return xstream.toXML(videoMessage);    }    /**     * 音乐消息对象转换成xml     *      * @param musicMessage 音乐消息对象     * @return xml     */    public static String messageToXml(MusicMessage musicMessage) {        xstream.alias("xml", musicMessage.getClass());        return xstream.toXML(musicMessage);    }    /**     * 图文消息对象转换成xml     *      * @param newsMessage 图文消息对象     * @return xml     */    public static String messageToXml(NewsMessage newsMessage) {        xstream.alias("xml", newsMessage.getClass());        xstream.alias("item", new Article().getClass());        return xstream.toXML(newsMessage);    }}

 

使用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 respXml = CoreService.processRequest(request);        // 响应消息        PrintWriter out = response.getWriter();        out.print(respXml);        out.close();    }}

 

使用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 xml     */    public static String processRequest(HttpServletRequest request) {        // xml格式的消息数据        String respXml = null;        // 默认返回的文本消息内容        String respContent = "未知的消息类型!";        try {            // 调用parseXml方法解析请求消息            Map<String, String> requestMap = MessageUtil.parseXml(request);            // 发送方帐号            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);            // 将文本消息对象转换成xml            respXml = MessageUtil.messageToXml(textMessage);        } catch (Exception e) {            e.printStackTrace();        }        return respXml;    }}

 

然后部署到我们的BAE上面,体验一下。(部署方法请参照 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发)。

 

效果如下:

 

 

 

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表