• 3.消息的自动回复


    公众号接收到关注者发来的消息,或者系统推送事件会统一发送到我们定义的接口,交给我们处理。

    上节课那个接口的doGet方法处理验证功能,今天doPost方法我们来接受公众号推送过来的消息。

     1     public void doGet(HttpServletRequest request, HttpServletResponse response)
     2             throws ServletException, IOException {
     3 
     4         // 微信加密签名  
     5         String signature = request.getParameter("signature");  
     6         // 时间戳  
     7         String timestamp = request.getParameter("timestamp");  
     8         // 随机数  
     9         String nonce = request.getParameter("nonce");  
    10         // 随机字符串  
    11         String echostr = request.getParameter("echostr");  
    12   
    13         PrintWriter out = response.getWriter();  
    14         // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败  
    15         if (SignUtil.checkSignature(signature, timestamp, nonce)) {  
    16             out.print(echostr);  
    17         }  
    18         out.close();  
    19         out = null;
    20     }
    21 
    22     public void doPost(HttpServletRequest request, HttpServletResponse response)
    23             throws ServletException, IOException {
    24         try {
    25             // 将请求、响应的编码均设置为UTF-8(防止中文乱码)  
    26             request.setCharacterEncoding("UTF-8");  
    27             response.setCharacterEncoding("UTF-8");   
    28             // 调用核心业务类接收消息、处理消息  
    29             String respMessage = MessageUtil.processRequest(request);
    30             if (!StringUtil.isEmpty(respMessage)) {
    31                 // 响应消息  
    32                 PrintWriter out = response.getWriter();  
    33                 out.print(respMessage);
    34                 out.close();
    35             }
    36         } catch (Exception e) {
    37             // TODO Auto-generated catch block
    38             e.printStackTrace();
    39         }  
    40     }
    41 
    42     public void init() throws ServletException {
    43     }
    44 }

    所以自动回复的关键在于解析公众号推送的消息,并解析,进行处理后,通过out.print();将消息返回给公众号,微信后台会帮我们发送给我们定义的某些人。

    下面来看看消息处理工具类 MessageUtil.java

    public static String processRequest(HttpServletRequest request) {  
            String respMessage = null;  
            try {  
                // 默认返回的文本消息内容  
                String respContent = "请求处理异常,请稍候尝试!";  
      
                // xml请求解析  
                Map<String, String> requestMap = MessageUtil.parseXml(request);  
      
                // 发送方帐号(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.RESP_MESSAGE_TYPE_TEXT);  
                textMessage.setFuncFlag(0);  
      
                // 文本消息  
                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_LOCATION)) {  
                    respContent = "您发送的是地理位置消息!";  
                }  
                // 链接消息  
                else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {  
                    respContent = "您发送的是链接消息!";  
                }  
                // 音频消息  
                else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {  
                    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_CLICK)) {  
                        // TODO 自定义菜单权没有开放,暂不处理该类消息  
                    }  
                }  
      
                textMessage.setContent(respContent);  
                respMessage = textMessageToXml(textMessage);  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
      
            return respMessage;  
        }  
        /** 
     * 文本消息对象转换成xml 
     *  
     * @param textMessage 文本消息对象 
     * @return xml 
     */  
    public static String textMessageToXml(TextMessage textMessage) {  
        xstream.alias("xml", textMessage.getClass());  
        return xstream.toXML(textMessage);  
    }  
      
    /** 
     * 音乐消息对象转换成xml 
     *  
     * @param musicMessage 音乐消息对象 
     * @return xml 
     */  
    public static String musicMessageToXml(MusicMessage musicMessage) {  
        xstream.alias("xml", musicMessage.getClass());  
        return xstream.toXML(musicMessage);  
    }  
      
    /** 
     * 图文消息对象转换成xml 
     *  
     * @param newsMessage 图文消息对象 
     * @return xml 
     */  
    public static String newsMessageToXml(NewsMessage newsMessage) {  
        xstream.alias("xml", newsMessage.getClass());  
        xstream.alias("item", new Article().getClass());  
        return xstream.toXML(newsMessage);  
    }  
      
    /** 
     * 扩展xstream,使其支持CDATA块 
     *  
     * @date 2013-05-19 
     */  
    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);  
                    }  
                }  
            };  
        }  
    });  
        

    TextMessage类

    public class BaseMessage {  
        // 开发者微信号  
        private String ToUserName;  
        // 发送方帐号(一个OpenID)  
        private String FromUserName;  
        // 消息创建时间 (整型)  
        private long CreateTime;  
        // 消息类型(text/image/location/link)  
        private String MsgType;  
        // 消息id,64位整型  
        private long MsgId;  
      
        public String getToUserName() {  
            return ToUserName;  
        }  
      
        public void setToUserName(String toUserName) {  
            ToUserName = toUserName;  
        }  
      
        public String getFromUserName() {  
            return FromUserName;  
        }  
      
        public void setFromUserName(String fromUserName) {  
            FromUserName = fromUserName;  
        }  
      
        public long getCreateTime() {  
            return CreateTime;  
        }  
      
        public void setCreateTime(long createTime) {  
            CreateTime = createTime;  
        }  
      
        public String getMsgType() {  
            return MsgType;  
        }  
      
        public void setMsgType(String msgType) {  
            MsgType = msgType;  
        }  
      
        public long getMsgId() {  
            return MsgId;  
        }  
      
        public void setMsgId(long msgId) {  
            MsgId = msgId;  
        }  
    }
    /** 
     * 文本消息 
     *  
     * @author liufeng 
     * @date 2013-05-19 
     */  
    public class TextMessage extends BaseMessage {  
        // 消息内容  
        private String Content;  
      
        public String getContent() {  
            return Content;  
        }  
      
        public void setContent(String content) {  
            Content = content;  
        }  
    }  

    额外的jar包(xstream-1.3.1.jar):http://download.csdn.net/detail/yaohucaizi/5120422

    更多可以到这个链接查看:http://blog.csdn.net/gebitan505/article/details/24500193

  • 相关阅读:
    (404) 未找到 获取StatusCode状态码
    通过UserAgent判断设备为Android、Ios、Pc访问
    Sql视图创建语句及修改视图
    301重定向
    md5加密篇(一)
    黑客编程教程(六)Windows的关机和重起
    黑客编程教程(五)多线程编程介绍
    黑客编程教程(四)关于服务器和客户端编程
    黑客编程教程(三)Windows 网络协议
    黑客编程教程(二)Win API编程简介
  • 原文地址:https://www.cnblogs.com/lijile/p/5133638.html
Copyright © 2020-2023  润新知