本文主要讲述了如何在微信公众平台实现消息接收以及消息的处理,使用java语言开发,现在把实现思路和代码整理出来分先给兄弟们,希望给他们带来帮助。

温馨提示:

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

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

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

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

首先,我们看看原来写的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 

* 描述: 消息处理工具类

* 开发人员: souvc 

* 创建时间:  2015-9-30 

* 发布版本:V1.0  

 */
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
     * @throws Exception
     */
    @SuppressWarnings("unchecked")
    public static Map parseXml(HttpServletRequest request) throws Exception {
        // 将解析结果存储在HashMap中
        Map map = new HashMap();

        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List 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("");
                    } 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 

 * 描述: 来接收微信服务器传来信息 

 * 开发人员: souvc

 * 创建时间:2015-9-29 

 * 发布版本:V1.0 

 */
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 

* 描述: 核心服务类 

* 开发人员: souvc 

* 创建时间:  2015-9-30 

* 发布版本:V1.0  

 */
public class CoreService {
    /**
     * 处理微信发来的请求
     * @param request
     * @return xml
     */
    public static String processRequest(HttpServletRequest request) {
        // xml格式的消息数据
        String respXml = null;
        // 默认返回的文本消息内容
        String respContent = "未知的消息类型!";
        try {
            // 调用parseXml方法解析请求消息
            Map 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上面,体验一下。(部署方法请参照 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发)。

效果如下:

微信开发——微信公众平台实现消息接收以及消息的处理(Java版)的更多相关文章

  1. 《微赢微信公众平台系统5月14最新破解高级运营版+水果机+邀请函+微汽车+微食品+用户CRM》

    <微赢微信公众平台系统5月14最新破解高级运营版+水果机+邀请函+微汽车+微食品+用户CRM> 此版本号眼下是淘宝卖600RMB的,其他VIP源代码论坛也都还没有公布.咱们这里全然免费分享 ...

  2. C# asp.net 搭建微信公众平台(可实现关注消息与消息自动回复)的代码以及我所遇到的问题

    [引言] 利用asp.net搭建微信公众平台的案例并不多,微信官方给的案例是用PHP的,网上能找到的代码很多也是存在着这样那样的问题或者缺少部分方法,无法使用,下面是我依照官方文档写的基于.net 搭 ...

  3. Java使用HTTPClient3.0.1开发的公众平台消息模板的推送功能

    package com.company.product.manager.busniess.impl; import java.io.IOException;import java.nio.charse ...

  4. 浅析微信支付:公众平台卡券功能开通、HTML5线上发券(JS-SDK接口)、查看卡券详情

    本文是[浅析微信支付]系列文章的第十六篇,主要讲解如何使用微信公众平台的卡券功能.如何使用HTML5在网页展示用户领券以及微信卡券和商户平台代金券的关系. 浅析微信支付系列已经更新十六篇了哟-,没有看 ...

  5. 【微信开发】公众号后台设置错误导致的微信redirect_uri参数错误【图】

    在微信开发中,如微信网页授权登录,分享到朋友圈自定义内容,微信h5支付时 可能会遇到微信redirect_uri参数错误的情况. 此时除了检查自己代码正确性外,还要检查一下是否正确地设置了公众号后台的 ...

  6. 对于微信UnionID在公众平台以及小程序里面的获取

    首先介绍下UnionID的作用,在注册了微信开放平台(注意,这里是开放平台,不是微信公众平台)之后,同一个微信号在这个开放平台下的项目上面的UnionID都是统一的,通俗的说就是,小程序跟公众号项目在 ...

  7. 使用delphi+intraweb进行微信开发1--微信平台接入

    示例代码已经放出!请移步使用delphi+intraweb进行微信开发1~4代码示例进行下载,虽为示例代码但是是从我项目中移出来的,封装很完备适于自行扩展和修改. iw14.0.50来了,在新的版本中 ...

  8. C#微信开发-微信JS-SDK(1)之通过config接口注入权限验证配置

    官方文档是微信JS-SDK的使用步骤http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#JSSDK.E4.BD.B ...

  9. html 微信开发——微信授权

    微信JS-SDK说明文档 链接地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html 微信web开发:http: ...

随机推荐

  1. 《LeetBook》leetcode题解(9):Palindrome Number[E]——回文数字

    我现在在做一个叫<leetbook>的开源书项目,把解题思路都同步更新到github上了,需要的同学可以去看看 地址:https://github.com/hk029/leetcode 这 ...

  2. 趣说Java:我是一个线程

    第一回 初生牛犊 我是一个线程,我一出生就被编了个号:0x3704,然后被领到一个昏暗的屋子里,在这里我发现了很多和我一模一样的同伴. 我身边的同伴0x6900 待的时间比较长,他带着沧桑的口气对我说 ...

  3. FX4300超频4.7GHz

    先贴出本人计算机配置: (本人cpu为fx4300,默认频率为3.8GHz) 谨记:超频有风险,很可能烧坏主板.cpu.内存等硬件,特别是增加主板电压时一定一次增加0.025V,不要一次增加太多,并且 ...

  4. Mac 安装Git

    一.安装 在进行安装前,要说一下,Git和SVN一样,都需要创建一个服务器的,他们都可以创建自己的版本管理服务器.对于个人和小团队来说,使用托管服务器可能更合适. 常见的有Github 和 Bitbu ...

  5. Nginx教程(6) 动静分离架构

    一.原理 Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离.严格意义上说应该是动态请求跟静态请求分开,可以理解成使用Nginx 处理静态页面,To ...

  6. java实现插入排序算法 附单元测试源码

    插入排序算法 public class InsertSortTest { /** * @param args */ public static void main(String[] args) { i ...

  7. [转]OPEN(SAP) UI5 学习入门系列之一:扫盲与热身(上)

    本文转自:http://www.cnblogs.com/qianmarv/p/4671394.html 1 扫盲 什么是SAP Fiori? 了解SAP UI5必须要从SAP Fiori开始,两者概念 ...

  8. python爬虫实战(九)--------拉勾网全站职位(CrawlSpider)

    相关代码已经修改调试成功----2017-4-24 详情代码请移步我的github:https://github.com/pujinxiao/Lagou_spider 一.说明 1.目标网址:拉勾网 ...

  9. SSIS教程:创建简单的ETL包 -- 3. 添加日志(Adding Logging)

    Microsoft Integration Services 包含日志记录功能,可通过提供任务和容器事件跟踪监控包执行情况以及进行故障排除. 日志记录功能非常灵活,可以在包级别或在包中的各个任务和容器 ...

  10. Java编程基础知识总结大全(Ⅱ)

    7.类型转换 精度从高到低 double float long int short(char) byte (1)自动类型转换 将一个低精度---高精度 (2)强制类型转换 将一个高精度---低精度 ...