微信公衆號開發之消息開發(Java)

前提:服務端程序和微信測試平臺已經打通。
沒打通的可以參考我前面的文章。

公衆號開發新手快速上路(Java版本)

公衆號開發文檔:https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html

今天的主題是消息,我們主要完成兩個功能。
1、用戶通過關注測試公衆號平臺給服務端傳遞數據。
2、服務端對數據作出及時反饋。

1、用戶通過關注測試公衆號平臺給服務端傳遞數據。

申請到測試公衆號平臺的朋友,打開後臺,有個測試二維碼,關注一下就能給後臺發消息了。
在這裏插入圖片描述
關注公衆號以後,隨便在公衆號發幾條消息,他會給你提供的url地址發送一個post請求。我們可以把消息打印出來瞅瞅。
在這裏插入圖片描述
post請求發來的數據是一段xml格式的數據包(文檔裏有),長下面這個樣子。(意思就是什麼時間什麼人給誰發了什麼內容的什麼類型的消息)

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[this is a test]]></Content>
  <MsgId>1234567890123456</MsgId>
</xml>

用戶發送的類型分爲好多種,包括文本(表情也是文本),視頻,語音,位置等等。基本數據包長的都差不多,可以多發幾種打印出來看看。也可以參考官方文檔。
在這裏插入圖片描述

這麼一串xml我們通過程序將其轉換爲map,用的dom4j。這樣我們就能很好的對用戶發來的數據包物盡其用了。


    @PostMapping("/get")
    private String get(HttpServletRequest request) {
        Map<String, String> requestMap = weChatService.parse(request);
        System.out.println("requestMap="+requestMap);
        return "";
    }

	//解析XML =》 Map
    @Override
    public Map<String, String> parse(HttpServletRequest request) {
        Map<String, String> map = new HashMap<>();
        try {
            SAXReader saxReader = new SAXReader();
            Document document = saxReader.read(request.getInputStream());
            Element root = document.getRootElement();
            List<Element> elements = root.elements();
            for (Element element : elements) {
                map.put(element.getName(), element.getStringValue());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
2、服務端對數據作出及時反饋。

接下來要對用戶發來的消息作出一個反饋,很簡單,只要在response一段xml數據就好了。
在這裏插入圖片描述
這個xml格式是有要求的,大概是這個樣子。

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[你好]]></Content>
</xml>

toUserName是接收map裏的fromUserName,fromUserName同理反一下。
CreateTime就是當前時間,System.currentTimeMillis() / 1000
MsgType和上面一樣,分爲文本,圖片,視頻等等。
想要簡單粗暴的方法直接在controller裏直接return上面一段數據就行了(注意不要出現空格)

我這邊封裝了一個對象,用工具類(XStream)將對象轉爲xml返回。
封裝的時候發現ToUserName,FromUserName,CreateTime一定有,就抽取成一個base類了。

/**
 * 公衆號開發自動回覆的基礎類
 */
public class BaseMessage {
    @XStreamAlias("ToUserName")
    private String toUserName;

    @XStreamAlias("FromUserName")
    private String fromUserName;

    @XStreamAlias("CreateTime")
    private String createTime;

    @XStreamAlias("MsgType")
    private String msgType;

    public BaseMessage(Map<String,String> requestMap, String msgType) {
        this.toUserName = requestMap.get("FromUserName");
        this.fromUserName = requestMap.get("ToUserName");
        this.createTime = System.currentTimeMillis() / 1000 + "";
        this.msgType = msgType;
    }

    public String getToUserName() {
        return toUserName;
    }

    public void setToUserName(String toUserName) {
        this.toUserName = toUserName;
    }

    public String getFromUserName() {
        return fromUserName;
    }

    public void setFromUserName(String fromUserName) {
        this.fromUserName = fromUserName;
    }

    public String getCreateTime() {
        return createTime;
    }

    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }

    public String getMsgType() {
        return msgType;
    }

    public void setMsgType(String msgType) {
        this.msgType = msgType;
    }
}

然後文本消息或者其他視頻消息,圖文消息在繼承這個Base類。

/**
 * 公衆號開發自動回覆文本消息類
 */
@XStreamAlias("xml")
public class TextMessage extends BaseMessage {

    @XStreamAlias("Content")
    private String content;


    public TextMessage(Map<String, String> requestMap, String content) {
        super(requestMap, "text");
        this.content = content;
    }
}

Controller就只要將對象轉爲數據返回就行

 	@PostMapping("/get")
    private String get(HttpServletRequest request) {
        Map<String, String> requestMap = weChatService.parse(request);
        System.out.println("requestMap="+requestMap);

        String response = weChatService.getResponse(requestMap);
        System.out.println(response);

        return response;
    }

service

 //回覆消息模板
// <xml>
//  <ToUserName><![CDATA[toUser]]></ToUserName>
//  <FromUserName><![CDATA[fromUser]]></FromUserName>
//  <CreateTime>12345678</CreateTime>
//  <MsgType><![CDATA[text]]></MsgType>
//  <Content><![CDATA[你好]]></Content>
//</xml>
    @Override
    public String getResponse(Map<String, String> requestMap) {
        String type = requestMap.get("MsgType");

        String responseXml = "";
        switch (type) {
            case "text":
                responseXml = dealTextMessage(requestMap);
                break;
            case "image":
                break;
            case "voice":
                break;
            case "video":
                break;
            case "music":
                break;
            case "news":
                break;
        }
        return responseXml;
    }



    //處理文本信息回覆
    private String dealTextMessage(Map<String, String> requestMap) {
        TextMessage textMessage = new TextMessage(requestMap, "hello ~~");
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);//激活註解
        xStream.alias("xml", TextMessage.class);
        return xStream.toXML(textMessage);
    }

大致過程就是這樣,以上我只是舉text爲例子,其他類型可能也有些許不同,換湯不換藥~ 大家可以試試。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章