码迷,mamicode.com
首页 > 微信 > 详细

微信公众平台开发之处理普通消息---2

时间:2015-08-26 00:05:52      阅读:410      评论:0      收藏:0      [点我收藏+]

标签:消息管理   微信开发平台   消息接收   消息回复   

(接上一篇文章:微信公众平台开发之处理普通消息---1)

本章节主要讲述对普通消息的处理。

当用户关注微信公众号时,取消关注时,给公众号发各种信息时,作出简单的响应(处理)。


一、在com.cc.wechat.util包下新建工具类:

---MessageUtil:

对xml解析需要用到两个工具包:

1 xstream.jar 点击下载

2 dom4j.jar 点击下载

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

微信公众平台开发之处理普通消息---2

标签:消息管理   微信开发平台   消息接收   消息回复   

原文地址:http://chn0515.blog.51cto.com/10646281/1688187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!