目录

前言

上一篇我们说了响应与接收,这一篇模拟公众平台的关注自动回复菜单,并对菜单序号回复相应内容。

来看看微信的 关注/取消关注事件Event ,关注里又分subscribe(关注)、unsubscribe(取消关注)

微信公众号开发 - 3.消息的接收与响应之关注自动回复

实现

在我们之前的代码基础上修改,添加以后可能会用到的消息类型,把之前的消息类型全部替换为常量,需要的各个回复单独写成方法。

package cn.notemi.util;

import cn.notemi.po.TextMessage;
import com.thoughtworks.xstream.XStream;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Title:MessageUtil
 * Description:消息的转换
 *
 * @author Flicker
 * @create 2017-07-25 下午 8:19
 **/
public class MessageUtil {

    public static final String MESSAGE_TEXT = "text";
    public static final String MESSAGE_IMAGE = "image";
    public static final String MESSAGE_VOICE = "voice";
    public static final String MESSAGE_VIDEO = "video";
    public static final String MESSAGE_LINK = "link";
    public static final String MESSAGE_LOCATION = "location";
    public static final String MESSAGE_EVENT = "event";
    public static final String MESSAGE_SUBSCRIBE = "subscribe";
    public static final String MESSAGE_UNSUBSCRIBE = "unsubscribe";
    public static final String MESSAGE_CLICK = "CLICK";
    public static final String MESSAGE_VIEW = "VIEW";
    /**
     * 将xml转为Map集合
     * @param request
     * @return
     * @throws Exception
     */
    public static Map<String,String> xmlToMap(HttpServletRequest request) throws Exception{
        Map<String,String> map = new HashMap<String, String>();
        SAXReader reader = new SAXReader();

        InputStream ins = request.getInputStream();
        Document doc = reader.read(ins);

        Element root = doc.getRootElement();

        List<Element> list = root.elements();

        for (Element e:list){
            map.put(e.getName(),e.getText());
        }
        ins.close();
        return map;
    }

    /**
     * 将文本消息对象转为xml
     * @param textMessage
     * @return
     */
    public static String textMessageToXml(TextMessage textMessage){
        XStream xStream = new XStream();
        xStream.alias("xml",textMessage.getClass());
        return xStream.toXML(textMessage);
    }

    /**
     * 拼接文本消息
     * @param toUserName
     * @param fromUserName
     * @param content
     * @return
     */
    public static String inText(String toUserName,String fromUserName,String content){
        TextMessage text = new TextMessage();
        text.setFromUserName(toUserName);
        text.setToUserName(fromUserName);
        text.setMsgType(MessageUtil.MESSAGE_TEXT);
        text.setCreateTime(String.valueOf(new Date().getTime()));
        text.setContent(content);
        return MessageUtil.textMessageToXml(text);
    }

    /**
     * 主菜单
     * @return
     */
    public static String menuText(){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("欢迎您的关注,看菜单哦\n\n");
        stringBuffer.append("1.介绍\n");
        stringBuffer.append("2.看电影\n");
        stringBuffer.append("3.回复?调出此菜单");
        return stringBuffer.toString();
    }

    public static String firstMenu(){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("介绍介绍");
        return stringBuffer.toString();
    }

    public static String secondMenu(){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("看电影看电影");
        return stringBuffer.toString();
    }

    public static String nullText(String massage){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("您发送的是:"+massage);
        return stringBuffer.toString();
    }
}

Controller

根据消息来判断回复的内容

package cn.notemi.controller;

import cn.notemi.po.TextMessage;
import cn.notemi.util.CheckUtil;

import cn.notemi.util.MessageUtil;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

/**
 * Title:WeixinController
 * Description:
 *
 * @author Flicker
 * @create 2017-07-25 下午 6:15
 **/
@Controller
@RequestMapping(value = "/weixin")
public class WeixinController {

    private static Logger logger = Logger.getLogger(WeixinController.class);

    @RequestMapping(value = "/connect",method = RequestMethod.GET)
    public void connect(HttpServletResponse response, HttpServletRequest request) throws Exception{
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");

        PrintWriter out = response.getWriter();
        if (CheckUtil.checkSignature(signature,timestamp,nonce)){
            out.print(echostr);
            logger.info("写入返回值成功");
        }
    }

    @RequestMapping(value = "/connect",method = RequestMethod.POST)
    public void message(HttpServletRequest request,
                        HttpServletResponse response)throws Exception{

        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();

        Map<String,String> map = MessageUtil.xmlToMap(request);
        String toUserName = map.get("ToUserName");
        String fromUserName = map.get("FromUserName");
        String createTime = map.get("CreateTime");
        String msgType = map.get("MsgType");
        String content = map.get("Content");
        String msgId = map.get("MsgId");

        String message = null;
        if (MessageUtil.MESSAGE_TEXT.equals(msgType)){
            if ("1".equals(content)){
                message = MessageUtil.inText(toUserName,fromUserName,MessageUtil.firstMenu());
            }else if("2".equals(content)){
                message = MessageUtil.inText(toUserName,fromUserName,MessageUtil.secondMenu());
            }else if ("?".equals(content)||"?".equals(content)){
                message = MessageUtil.inText(toUserName,fromUserName,MessageUtil.menuText());
            }else {
                message = MessageUtil.inText(toUserName,fromUserName,MessageUtil.nullText(content));
            }
        }else if (MessageUtil.MESSAGE_EVENT.equals(msgType)){
            String eventType = map.get("Event");
            //关注自动回复
            if (MessageUtil.MESSAGE_SUBSCRIBE.equals(eventType)){
                message = MessageUtil.inText(toUserName,fromUserName,MessageUtil.menuText());
            }
        }
        logger.info(message);
        out.print(message);
        out.close();
    }
}

测试

微信公众号开发 - 3.消息的接收与响应之关注自动回复