(7)java代码实现微信消息交互案例

来源:互联网 发布:towedm线切割编程系统 编辑:程序博客网 时间:2024/06/03 17:29

微信将用户发送的消息分成两种,一种是普通消息,另一种是事件推送消息。其中普通消息又有8种类型,分别是文本,图片,语音,视频,小视频,地理位置,链接消息。

1 普通消息

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。这句话对理解微信开发很重要,你还记得微信服务器什么时候会发送GET请求到URL上吗?没错,就是在服务器配置哪里。

微信服务器要么发get请求,要么发post请求给我的服务器,所以我的服务器中只需要分别重载HttpServlet的doGet和doPost方法即可,如下图所示:

这里写图片描述

doGet方法,用来验证是否正确接入微信服务器。
doPost方法,用来处理用户发来的请求。

2 消息交互流程图

这是一张微信官方的消息交互流程图,说明了开发者服务器接受消息的过程。

这里写图片描述

再配合下面这样更直观的图,相信你已经有所领悟了。

这里写图片描述

微信服务器与我的服务器之间的数据都需要二次加工的,即数据被包装成固定的 xml格式。

注意:![CDATA[ ]]>是什么意思?(由于我现在使用的markdown编辑器,!左边的小括号我写不出来,会被转义)

答案: ![CDATA[ ]]>里面的语句不会被解析器解析,防止语句中出现转义字符会被转义。

3 java代码实现text消息前后端交互案例(根据用户发送消息,回复消息)
3.1 重载的doPost方法:

    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        req.setCharacterEncoding("UTF-8");        resp.setCharacterEncoding("UTF-8");        String responseMessage = coreService.processRequest(req);//工具类 coreService的processRequest方法处理用户请求        PrintWriter out = resp.getWriter();        out.print(responseMessage);        out.close();    }

3.2 工具类coreServlet:

public class coreService {    public static String processRequest(HttpServletRequest request) {        String responseContent = "初始化信息";        String responseMessage = "success";//ֱ保证微信服务器5秒内能接受到回复        try {            Map<String, String> map = messageUtil.xmlToMap(request);//利用写好的工具类将微信服务器发来的xml格式消息解析到map里            //从map中拿到相应参数ֵ            String fromUserName = map.get("FromUserName");            String toUserName = map.get("ToUserName");            String msgType = map.get("MsgType");            System.out.println("用户发送的消息类型:"+msgType);            if (messageUtil.resp_message_type_text.equals(msgType)) {//如果用户发送的是text类型的消息                if ("A".equals(map.get("Content").toUpperCase())){                    responseContent="模拟用户发送A后,服务器推送相应的内容";                  }                else if ("B".equals(map.get("Content").toUpperCase())) {                    responseContent="模拟用户发送B后,服务器推送相应的内容";                }                else if ("?".equals(map.get("Content"))) {                    responseContent="?让我不知错所";                }                else {                    responseContent="请老老实实发送A,B或者英文格式的?";                }            }            else if (messageUtil.resp_message_type_event.equals(msgType)) {//如果用户发送的是event类型的消息                    System.out.println(map);                if ("subscribe".equals(map.get("Event"))) {                    responseContent="很荣幸,您订阅了此公众号!\n发送A,查看A菜单写信息。\n发送B,查看B菜单写信息。\n发送?,我们将指引你前行。";                }                else if ("unsubscribe".equals(map.get("Event"))) {                    responseContent="很遗憾,你取消了本公众号!";                }            }            //再拼装xml格式的返回消息,发送给微信服务器            textMessage text = new textMessage();            text.setFromUserName(toUserName);            text.setToUserName(fromUserName);            text.setCreateTime(new Date().getTime());            text.setMsgType(messageUtil.resp_message_type_text);            text.setContent(responseContent);            System.out.println("消息接收方="+text.getToUserName()+",发送方="+text.getFromUserName()+",消息内容="+text.getContent());            responseMessage = messageUtil.mapToXml(text);//利用写好的工具类将text类型消息拼装成微信服务器接受的xml格式            System.out.println("回复给微信服务器的text消息:\n"+responseMessage);        }         catch (Exception  e) {            e.printStackTrace();        }        return responseMessage;    }}

3.3 工具类messageUtil

package zk.util;import zk.entity.textMessage;其他包省略,自行包入public class messageUtil {    public final static String resp_message_type_text = "text";    public final static String resp_message_type_event = "event";    public static Map<String, String> xmlToMap(HttpServletRequest request) throws  Exception {        Map<String, String> map = new HashMap<String,String>();        InputStream inputStream = request.getInputStream();        SAXReader reader = new SAXReader();        Document read = reader.read(inputStream);        Element rootElement = read.getRootElement();        List<Element> elements = rootElement.elements();        System.out.println("*******************************");        for (Element element : elements) {            System.out.println(element.getName()+":"+element.getText());            map.put(element.getName(), element.getText());        }        System.out.println("*******************************");        inputStream.close();        return map;    }    public static String mapToXml(textMessage text){        XStream stream = new XStream();        System.out.println(stream.toXML(text));//全类名<zk.entity.textMessage>        stream.alias("xml",text.getClass());//首尾全类名改成<xml>        return stream.toXML(text);    }}

注意
mapToXml方法,stream.toXML(text)的输出结果格式为:

这里写图片描述

修改类型别名stream.alias(“xml”,text.getClass())后的输出格式才能被微信服务器识别:

这里写图片描述

4 测试text类型消息

1)开启natapp.exe

这里写图片描述

2)开启后台服务器(Tomcat)

这里写图片描述

3)手机微信关注测试公众号之后给公众号发送text消息

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

原创粉丝点击