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

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

时间: 2024-10-07 03:45:22

微信公众平台开发之处理普通消息---2的相关文章

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

注:我的培训老师:柳峰,在此感谢柳老师!他的个人博客:http://blog.csdn.net/lyq8479 用户发送的消息包括: (参照官方微信公众开发平台:http://mp.weixin.qq.com/wiki/) 1 文本消息,包括: ToUserName---开发者微信号 FromUserName---发送方帐号(一个OpenID) CreateTime---消息创建时间 (整型) MsgType---text Content---文本消息内容 MsgId---消息id,64位整型

微信公众平台开发(十) 消息回复总结——用其xml模板

一.简介 微信公众平台提供了三种消息回复的格式,即文本回复.音乐回复和图文回复,在这一篇文章中,我们将对这三种消息回复的格式做一下简单讲解,然后封装成函数,以供读者使用. 二.思路分析 对于每一个POST请求,开发者在响应包中返回特定xml结构,对该消息进行响应(现支持回复文本.图文.语音.视频.音乐). 三.文本回复 3.1 文本回复xml 结构 <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <F

微信公众平台开发(2)-消息封装

微信公众平台开发(2)-消息处理 消息包括文本.图片.语音.视频.音乐.图文,消息格式参考http://mp.weixin.qq.com/wiki/index.php?title=发送被动响应消息 在接入接口时指定了回调URL,在保存时微信会以GET方式调用此URL,并将signature,timestamp,nonce,echostr添加到URL上 因此在我们的微信处理的Controller中需要有执行上面URL的GET方法. 那么,发送和接收消息怎么来实现呢? 这个是通过以POST方式调用上

微信公众平台开发(26) 消息回复总结

原文: http://www.cnblogs.com/imaker/p/5491433.html 一.简介 微信公众平台提供了三种消息回复的格式,即文本回复.音乐回复和图文回复,在这一篇文章中,我们将对这三种消息回复的格式做一下简单讲解,然后封装成函数,以供读者使用. 二.思路分析 对于每一个POST请求,开发者在响应包中返回特定xml结构,对该消息进行响应(现支持回复文本.图文.语音.视频.音乐). 三.文本回复 3.1 文本回复xml 结构 <xml> <ToUserName>

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

微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者配置的URL和Token 来找到第三方服务器,并以XML形式向第三方服务器发送消息. (3)第三方服务器获取这些消息之后,需要按照微信服务器传过来的XML的语言进行解析,获取到信息之后,根据用户的需求,提供服务,然后封装成XML数据,传回到微信服务器上去. (4)微信服务器解析这些XML,并把相应的

cgi程序读取post发送的特殊字符,尤其适合于微信公众平台开发中发送被动消息

[问题]用c编写cgi程序怎样取出html表单post来的数据? [分析]html表单post来的数据形如username="zhang"&&password="123456"&&useid="012" [方法1]lainco #include <stdio.h> #include <stdlib.h> #include <string.h> char *getcgidata(F

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

温馨提示: 这篇文章是依赖前几篇的文章的. 第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发 第三篇 :微信公众平台开发实战之请求消息,响应消息以及事件消息类的封装 首先,我们看看原来写的dopost方法: /** * 处理微信服务器发来的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) thr

微信公众平台开发入门教程

在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/JS等基础. 我们将使用微信公众账号方倍工作室作为讲解的例子,二维码见底部. 本系列教程将引导你完成如下任务: 创建新浪云计算平台应用 启用微信公众平台开发模式 基础接口消息及事件 微信公众平台PHP SDK 微信公众平台开发模式原理 开发天气预报功能 第一章 申请服务器资源 创建新浪云计算应用 申请账号 我们使用SAE新浪云计算平台作为服务器资源,并且申请PHP环境+M

微信公众平台开发(学习)1

在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/JS等基础. 我们将使用微信公众账号方倍工作室作为讲解的例子,二维码见底部. 本系列教程将引导你完成如下任务: 创建新浪云计算平台应用 启用微信公众平台开发模式 基础接口消息及事件 微信公众平台PHP SDK 微信公众平台开发模式原理 开发天气预报功能 第一章 申请服务器资源 创建新浪云计算应用 申请账号 我们使用SAE新浪云计算平台作为服务器资源,并且申请PHP环境+M