2.微信公众号服务器配置启用后的消息接收

微信服务器配置完成之后,我们需要定义接口来接收公众号所发生的事件和消息

1.微信公众号中的消息传递是以服务器地址的post请求方式发送过来的。

2.微信与服务器之间的通讯是以xml之间进行通讯的。maven依赖

 
            com.thoughtworks.xstream
            xstream
            1.4.9
        
将对象转换为xml

            dom4j
            dom4j
            1.6.1
        
xml解析

3.代码

@Path("weixin")
public class WeXinResource
{
 @Autowired
    private EventDispatcher eventDispatcher;//事件处理器
    @Autowired
    private MsgDispatcher msgDispatcher;//消息处理器

    @POST
    @Path("messgae")
    @Produces(MediaType.TEXT_XML)
    public String returnMessage(InputStream is) throws IOException {
        try{
            Map map=MessageUtil.parseXml(is);
            String msgtype=map.get("MsgType");
            if(MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgtype)){
                String eventMessage =eventDispatcher.processEvent(map); //进入事件处理
                return eventMessage;
            }else{
                String processMessage= msgDispatcher.processMessage(map); //进入消息处理
                return processMessage;
            }

        }catch(Exception e){
            e.printStackTrace();
        }


        return "";
    }
package com.peas.business.weixin;

import com.peas.business.weixin.dto.*;
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;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by peaimage on 2018/8/14.
 */
public class MessageUtil {


    /**
     * ClassName: MessageUtil
     * @Description: 消息工具类
     * @author dapengniao
     * @date 视频类型
     */


    /**
     * 请求消息类型:文本
     */
    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_LINK = "link";

    /**
     * 请求消息类型:地理位置
     */
    public static final String REQ_MESSAGE_TYPE_LOCATION = "location";

    /**
     * 请求消息类型:音频
     */
    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 RESP_MESSAGE_TYPE_NEWS = "news";



    // 临时二维码
    public static final String QR_SCENE = "QR_SCENE"; //-1
    // 永久二维码
    public static final String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";//0
    // 永久二维码(字符串)
    public static final String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";//1

    public static final String LONG2SHORT = "long2short";











    /**
     * 请求消息类型:推送
     */
    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";

    /**
     * 事件类型:VIEW(点击菜单跳转链接时的事件推送)
     */
    public static final String EVENT_TYPE_VIEW = "VIEW";






    /**
         * @Description: 解析微信发来的请求(XML)
         */

        public static Map parseXml(InputStream ins) throws Exception {
            // 将解析结果存储在 HashMap 中
            Map map = new HashMap();
            SAXReader reader = new SAXReader();            // 使用dom4j解析xml
            Document doc = reader.read(ins);

            Element root = doc.getRootElement();         // 获取根元素
            List list = root.elements();        // 获取所有节点

            for (Element e : list) {
                map.put(e.getName(), e.getText());
                System.out.println(e.getName() + "--->" + e.getText());
            }
            ins.close();
            ins = null;
            return map;
        }
    /**
     * 对象到 xml 的处理
     */
    private static XStream xstream = new XStream(new XppDriver() {
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out) {
                // 对所有 xml 节点的转换都增加 CDATA 标记
                boolean cdata = true;
                @SuppressWarnings("rawtypes")
                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);
                    }
                }
            };
        }
    });

    public static String textMessageToXml(TextMessage textMessage) {
        xstream.alias("xml", textMessage.getClass());
        return xstream.toXML(textMessage);
    }

    /**
     * @Description: 图文消息对象转换成 xml
     */
    public static String newsMessageToXml(NewsMessage newsMessage) {
        xstream.alias("xml", newsMessage.getClass());
        xstream.alias("item", new Article().getClass());
        return xstream.toXML(newsMessage);
    }

    /**
     * @Description: 图片消息对象转换成 xml
     * @param @param imageMessage
     */
    public static String imageMessageToXml(ImageMessage imageMessage) {
        xstream.alias("xml", imageMessage.getClass());
        return xstream.toXML(imageMessage);
    }

    /**
     * @Description: 语音消息对象转换成 xml
     */
    public static String voiceMessageToXml(VoiceMessage voiceMessage) {
        xstream.alias("xml", voiceMessage.getClass());
        return xstream.toXML(voiceMessage);
    }

    /**
     * @Description: 视频消息对象转换成 xml
     */
    public static String videoMessageToXml(VideoMessage videoMessage) {
        xstream.alias("xml", videoMessage.getClass());
        return xstream.toXML(videoMessage);
    }

    /**
     * @Description: 音乐消息对象转换成 xml
     */
    public static String musicMessageToXml(MusicMessage musicMessage) {
        xstream.alias("xml", musicMessage.getClass());
        return xstream.toXML(musicMessage);
    }
}
package com.peas.business.weixin;




import com.peas.business.weixin.dto.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;

/**
 * Created by peaimage on 2018/8/14.事件处理器
 */
@Component
public class EventDispatcher {
    @Autowired
    private WeChatResource weChatResource;

    public  String processEvent(Map map) throws Exception {
        String openid=map.get("FromUserName"); //用户 openid
        String mpid=map.get("ToUserName");   //公众号原始 ID
        if (map.get("Event").equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { //关注事件
           System.out.println("==============关注事件!");
        }

        if (map.get("Event").equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) { //取消关注事件

            System.out.println("==============这是取消关注事件!");
        }

        if (map.get("Event").equals(MessageUtil.EVENT_TYPE_SCAN)) { //扫描二维码事件
              System.out.println("==============扫描二维码事件!");
        }

        if (map.get("Event").equals(MessageUtil.EVENT_TYPE_LOCATION)) { //位置上报事件
            System.out.println("==============这是位置上报事件!");
        }

        if (map.get("Event").equals(MessageUtil.EVENT_TYPE_CLICK)) { //自定义菜单点击事件
            System.out.println("==============这是自定义菜单点击事件!");
        }

        if (map.get("Event").equals(MessageUtil.EVENT_TYPE_VIEW)) { //自定义菜单 View 事件
            System.out.println("==============这是自定义菜单 View 事件!");
        }

        return null;
    }

}

package com.peas.business.weixin;


import com.peas.business.weixin.dto.Article;
import com.peas.business.weixin.dto.NewsMessage;
import com.peas.business.weixin.dto.TextMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.inject.Inject;

import java.util.ArrayList;
import java.util.Date;

import java.util.List;
import java.util.Map;

/**
 * Created by peaimage on 2018/8/14.
 */
@Component
public class MsgDispatcher {
    @Autowired
    private WeChatResource weChatResource;
    public  String processMessage(Map map) {
        String openid=map.get("FromUserName"); //用户 openid
        String mpid=map.get("ToUserName");   //公众号原始 ID

        if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { // 文本消息
            TextMessage txtMessgae=new TextMessage();
            txtMessgae.setToUserName(openid);
            txtMessgae.setFromUserName(mpid);
            txtMessgae.setCreateTime(new Date().getTime());
            txtMessgae.setMsgType(MessageUtil.REQ_MESSAGE_TYPE_TEXT);
            txtMessgae.setContent("nihao");
            return MessageUtil.textMessageToXml(txtMessgae);
        }

        if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) { // 图片消息
        
        }

        if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) { // 链接消息
            System.out.println("==============这是链接消息!");
        }

        if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) { // 位置消息
            System.out.println("==============这是位置消息!");
        }

        if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)) { // 视频消息
            System.out.println("==============这是视频消息!");
        }

        if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) { // 语音消息
            System.out.println("==============这是语音消息!");
        }
        if (map.get("MsgType").equals(MessageUtil.REQ_MESSAGE_TYPE_SHORTVIDEO)) { // 小视频消息
            System.out.println("==============这是小视频消息!");
        }

        return null;
    }
}

package com.peas.business.weixin.dto;

import lombok.Data;

/**
 * Created by peaimage on 2018/8/14.微信请求消息基本类
 */
@Data
public  class BaseMessage {
    // 开发者微信号
    private String ToUserName;
    // 发送方帐号(一个 OpenID)
    private String FromUserName;
    // 消息创建时间 (整型)
    private long CreateTime;
    // 消息类型(text/image/location/link/video/shortvideo)
    private String MsgType;
    // 消息 id,64 位整型
    private long MsgId;
    //消息文本
    private String Content;
}

package com.peas.business.weixin.dto;

import lombok.Data;

/**
 * Created by peaimage on 2018/8/14.
 * 文本消息
 */
@Data
public class TextMessage extends BaseMessage {
    // 消息内容
    private String Content;

}
package com.peas.business.weixin.dto;

import lombok.Data;

/**
 * Created by peaimage on 2018/8/14.
 *  视频/小视屏消息
 */
@Data
public class VideoMessage extends BaseMessage {
    private String MediaId; // 视频消息媒体 id,可以调用多媒体文件下载接口拉取数据
    private String ThumbMediaId; // 视频消息缩略图的媒体 id,可以调用多媒体文件下载接口拉取数据

}
package com.peas.business.weixin.dto;

import lombok.Data;

import java.util.List;

/**
 * Created by peaimage on 2018/8/14.
 */
@Data
public class NewsMessage extends BaseMessage {
    // 图文消息个数,限制为 10 条以内
    private int ArticleCount;
    // 多条图文消息信息,默认第一个 item 为大图
    private List
Articles; }
package com.peas.business.weixin.dto;

import lombok.Data;

/**
 * Created by peaimage on 2018/8/14.
 */
@Data
public class Music {
    private String Title;
    // 音乐描述
    private String Description;
    // 音乐链接
    private String MusicUrl;
    // 高质量音乐链接,WIFI 环境优先使用该链接播放音乐
    private String HQMusicUrl;

    private String ThumbMediaId; //缩略图的媒体 id

}

package com.peas.business.weixin.dto;

import lombok.Data;

/**
 * Created by peaimage on 2018/8/14.
 * 连接消息
 */
@Data
public class LinkMessage extends BaseMessage {
    // 消息标题
    private String Title;
    // 消息描述
    private String Description;
    // 消息链接
    private String Url;

}


package com.peas.business.weixin.dto;

import lombok.Data;

/**
 * Created by peaimage on 2018/8/14.
 * 图片消息
 *
 */
@Data
public class ImageMessage  extends BaseMessage {
    // 图片链接
    private String PicUrl;
}

package com.peas.business.weixin.dto;

import lombok.Data;

/**
 * Created by peaimage on 2018/8/14.
 */
@Data
public class Article {
    // 图文消息名称
    private String Title;
    // 图文消息描述
    private String Description;
    // 图片链接,支持 JPG、PNG 格式,较好的效果为大图 640*320,小图 80*80,
    private String PicUrl;
    // 点击图文消息跳转链接
    private String Url;
}

package com.peas.business.weixin.dto;


import lombok.Data;

/**
 * Created by peaimage on 2018/8/16.
 */
@Data
public class Action {
    private String action_name;
    private String expire_seconds;
    private T action_info;
}

@Data
public class VoiceMessage extends BaseMessage {
    // 媒体 ID
    private String MediaId;
    // 语音格式
    private String Format;
}

这样我们就根据msgtype消息类型的不同将消息分发到不同的消息处理器 在消息处理器中通过Event的值和MsgType的值将其具体分发具体处理.

你可能感兴趣的:(2.微信公众号服务器配置启用后的消息接收)