三、微信公众号开发--阐述消息的处理与接收流程

前言

        微信在接到消息后,会想设置好的url地址发送post形式的请求,开发者只要接收这个请求,解析之后做出响应的操作,然后按照响应的格式,把数据响应回去就好了。如果响应失败,微信没有接收到来自服务器的响应信息,或者响应的格式不对的话,前端会出现“目标服务器服务出现故障”等类似的提示;

正文

        首先是程序的入口,在servlet的doPost()方法中来处理这个请求。并返回响应的xml字符串;

@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 调用核心业务类接收消息、处理消息
        String respXml = MessageControl.getControl().processMessageRequest(request);
        //System.out.println("respxml"+respXml);
        // 响应消息
        PrintWriter out = response.getWriter();
        out.print(respXml);
        out.close();
		return;
	}
        逻辑很简单,因为代码量很少,就分两步,先是调用核心业务处理类MessageControl处理消息对象,然后得到的结果通过out流写出到页面;

        在MessageControl类中,写的大多是对于消息类型的判断还有对事件类型的判断,然后做出响应。

package com.wx.control;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.wx.service.ImageMsgService;
import com.wx.service.LinkMsgService;
import com.wx.service.LocationMsgService;
import com.wx.service.MenuService;
import com.wx.service.TextMsgService;
import com.wx.service.VideoMsgService;
import com.wx.service.VoiceMsgService;
import com.wx.service.impl.ImageMsgServiceImpl;
import com.wx.service.impl.LinkMsgServiceImpl;
import com.wx.service.impl.LocationMsgServiceImpl;
import com.wx.service.impl.MenuServiceImpl;
import com.wx.service.impl.TextMsgServiceImpl;
import com.wx.service.impl.VideoMsgServiceImpl;
import com.wx.service.impl.VoiceMsgServiceImpl;
import com.wx.util.MessageUtil;

import life.book.util.LogPersist;
import life.book.util.LogPersist.Path;
import life.book.util.Utils;

/**
 * User:Jiahengfei --> 17515250730@163.com
 * create by 2018年4月29日 from Eclipse.
 * describe:消息接收与回应控制器
 */
public class MessageControl implements Path{
	private static MessageControl control;
	private MessageControl(){}
	public static MessageControl getControl(){if(control==null){control=new MessageControl();}return control;}
	
	private TextMsgService text = new TextMsgServiceImpl();
	private VideoMsgService video = new VideoMsgServiceImpl();
	private ImageMsgService image = new ImageMsgServiceImpl();
	private VoiceMsgService link = new VoiceMsgServiceImpl();
	private LocationMsgService location = new LocationMsgServiceImpl();
	private LinkMsgService voice = new LinkMsgServiceImpl();
	
	private MenuService menu = new MenuServiceImpl();
	
	/**
     * 处理微信发来的请求
     * @param request
     * @return xml
     */
    public String processMessageRequest(HttpServletRequest request) {
    	// xml格式的消息数据
        String respXml = null;
        try {
            // 调用parseXml方法解析请求消息
            Map<String, String> map = MessageUtil.parseXml(request);
            // 消息类型
            String msgType = map.get("MsgType");
            
            //持久化日志
            String[] params = {Utils.getTime(),map.get("MsgType"),map.get("FromUserName"),map.get("Content")};
            LogPersist.getOperation().log().csv(this, params);
            System.out.println("AE:"+map.get("MsgType"));

            // 文本消息
            if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
            	respXml = text.dispose(map);
            }
            // 图片消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {
            	respXml = image.dispose(map);
            }
            // 语音消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {
            	respXml = voice.dispose(map);
            }
            // 视频消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)) {
            	respXml = video.dispose(map);
            }
            // 视频消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_SHORTVIDEO)) {
            	respXml = video.dispose(map);
            }
            // 地理位置消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {
            	respXml = location.dispose(map);
            }
            // 链接消息
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {
            	respXml = link.dispose(map);
            }
            // 事件推送
            else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {
                // 事件类型
                String eventType = map.get("Event");
                // 关注
                if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                	respXml = MessageUtil.Default.text(map, "谢谢你那么有才华还关注我
}
                // 取消关注
                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 处理菜单点击事件
                	String key = map.get("EventKey");
                	if (key!=null) {
                		respXml = menu.rstOnclickMenu(key, map);
					}
                }
            }
            if (respXml==null) {respXml = MessageUtil.Default.text(map, "您当前发送的信息暂无法自动识别,已移交客服处理,请等待客服回复,感谢您对我们的支持和理解!");}
        } catch (Exception e) {
            e.printStackTrace();
        }
        return respXml;
    }
	@Override
	public String gainPath() {
		return LogPersist.getOperation().path("wx/textmsg");
	}
}

        这个写的是不不知到抽什么风了,就是写出来显示不全,害我重写了好几遍!!!

        总结一下,用户发出信息之后,先传递给微信服务端,微信服务端把消息包装之后,传递给对应的开发者服务端进行数据的处理,开发者服务端接收之后,会对消息进行解析处理,解析成一个map集合,然后对于消息的类型进行判断,判断之后响应对应的服务来处理数据,处理结果包装成一个xml格式的字符串,返还给微信服务端,微信服务端解析数据之后再传递给客户端展示;
        在这个控制类中,我们做了几乎所有微信消息类型和事件推送类型的判断,并分别开启了相应的服务来处理这些问题,所以这个控制类写好之后,一般后面开发的过程中需求再怎么变,业务再怎么增加,这个类都不太会改变的。
        这就是处理微信公众号消息的全过程,至于具体的处理,下一章我以一个文本消息处理的案例进行解释;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值