一旦手把手教你開發微信公衆平臺2

目錄:

前言

最近忙於畢業設計,更新慢,希望大家見諒。

回顧

上一節我講了如何申請微信公衆平臺測試賬號、配置接口信息、搭建了開發環境,並且初步實現了微信服務器消息的驗證。

本節內容

  • 實現了微信的消息驗證之後,需要注意的是,每次微信服務器發送消息過來的時候,我們都需要進行驗證,避免有不法分子冒充微信平臺惡意發送消息。
  • 本節將會繼續講解,主要內容是消息接收。

準備工作

  • 這裏我給大家列出幾個工具類,這些工具類是我個人編寫的,應該不是很難,所以不會講解,只是給大家貼個代碼:
  • jacksonUtils:json解析工具(工具類以及精簡,比較複雜的方法也用不到)
package com.yd.app.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @Author 一旦
 * @Time 2014-*-*
 */
@SuppressWarnings("unchecked")
public class JacksonUtils {

    private static ObjectMapper objectMapper = null;

    static {
        objectMapper = new ObjectMapper();
    }

    /*
     * Write Object To Json
     */

    public static String writeObject2Json(Object o) throws JsonGenerationException, JsonMappingException, IOException {
        return objectMapper.writeValueAsString(o);
    }

    public static String writeEntity2Json(Object o) throws JsonGenerationException, JsonMappingException, IOException {
        return objectMapper.writeValueAsString(o);
    }

    public static String writeMap2Json(Map<String, Object> map) throws JsonGenerationException, JsonMappingException, IOException {
        return objectMapper.writeValueAsString(map);
    }

    public static String writeList2Json(List<?> list) throws JsonGenerationException, JsonMappingException, IOException {
        return objectMapper.writeValueAsString(list);
    }

    /*
     * Read Json To Object
     */

    public static <T> T readJson2ObjectFromString(String jsonStr, Class<?> clazz) throws JsonParseException, JsonMappingException, IOException {
        return (T) objectMapper.readValue(jsonStr, clazz);
    }

    public static <T> T readJson2ObjectFromStream(InputStream inputStream, Class<?> clazz) throws JsonParseException, JsonMappingException, IOException {
        return (T) objectMapper.readValue(inputStream, clazz);
    }

    public static <T> T readJson2ObjectFromByteArray(byte[] bytes, Class<?> clazz) throws JsonParseException, JsonMappingException, IOException {
        return (T) objectMapper.readValue(bytes, 0, bytes.length, clazz);
    }

}
  • xmlUtils:xml操作工具(xstream封裝,並且所以方法已經針對微信開發進行了特定優化)
package com.yd.wechat.utils;

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

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.io.xml.Dom4JDriver;

public class XmlUtils {

    /**
     * 獲取只有一層次的xml文檔,無屬性。 轉換爲map。
     * */
    public static Map<String, String> xml2Map(InputStream in) {

        Map<String, String> map = new HashMap<String, String>();

        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(in);

            Element root = document.getRootElement();
            List<Element> elements = root.elements();

            for (Element e : elements) {
                map.put(e.getName(), e.getText());
            }

            return map;

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

        return null;

    }

    public static String object2Xml(Object object) {
        try {
            XStream xstream = new XStream(new Dom4JDriver());
            return xstream.toXML(object);
        } catch (Exception e) {
        }
        return null;
    }

    public static String object2Xml(Object object, String alias) {
        try {
            XStream xstream = new XStream(new Dom4JDriver());
            if (alias != null)
                xstream.alias(alias, object.getClass());
            else
                xstream.alias(object.getClass().getSimpleName(), object.getClass());
            return xstream.toXML(object);

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

    /***
     * 如果alias不爲空,由調用者決定別名。 否則,默認只爲object對象指定一個別名爲其類的簡單名字。
     */
    public static String object2Xml(Object object, Map<String, Class<?>> alias) {
        try {
            XStream xstream = new XStream(new Dom4JDriver());

            if (alias != null) {
                for (Map.Entry<String, Class<?>> entry : alias.entrySet()) {
                    xstream.alias(entry.getKey(), entry.getValue());
                }
            } else {
                xstream.alias(object.getClass().getSimpleName(), object.getClass());
            }

            return xstream.toXML(object);

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

    public static <T> T xml2Object(String xml) {
        try {
            XStream xstream = new XStream(new Dom4JDriver());
            xstream.ignoreUnknownElements();
            return (T) xstream.fromXML(xml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T xml2Object(String xml, Class<?> clazz) {
        try {
            XStream xstream = new XStream(new Dom4JDriver());
            xstream.alias(clazz.getSimpleName(), clazz);
            xstream.ignoreUnknownElements();
            return (T) xstream.fromXML(xml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T xml2Object(String xml, Class<?> clazz, String alias) {
        try {
            XStream xstream = new XStream(new Dom4JDriver());
            xstream.alias(alias, clazz);
            xstream.ignoreUnknownElements();
            return (T) xstream.fromXML(xml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T xml2Object(String xml, Class<?> clazz, String alias, List<Converter> converters) {
        try {
            XStream xstream = new XStream(new Dom4JDriver());
            xstream.alias(alias, clazz);
            xstream.ignoreUnknownElements();

            if (converters != null && converters.size() > 0) {
                for (Converter converter : converters) {
                    xstream.registerConverter(converter);
                }
            }

            return (T) xstream.fromXML(xml);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

開發嘍

公共部分

  • 本人寫了幾個公用類,下面列代碼:
  • Message類(公用的接受消息父類)
package com.yd.wechat.message.common;

public class Message {

    protected MessageBody messageBody;

    public Message(MessageBody messageBody) {
        super();
        this.messageBody = messageBody;
    }

    /*******************************************************************************************************/
    /** 提供消息類型的判斷的方法 ***********************************************************************************/
    public boolean isTextMessage() {
        return MessageType.text.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isImageMessage() {
        return MessageType.image.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isVoiceMessage() {
        return MessageType.voice.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isVideoMessage() {
        return MessageType.video.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isShortVideoMessage() {
        return MessageType.shortvideo.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isLocationMessage() {
        return MessageType.location.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isLinkMessage() {
        return MessageType.link.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isEventMessage() {
        return MessageType.event.toString().equalsIgnoreCase(messageBody.MsgType);
    }

    public boolean isSubscribeEvent() {
        return isEventMessage() && EventType.subscribe.toString().equalsIgnoreCase(messageBody.Event) && messageBody.EventKey == null;
    }

    public boolean isUnSubscribeEvent() {
        return isEventMessage() && EventType.unsubscribe.toString().equalsIgnoreCase(messageBody.Event);
    }

    public boolean isSubscribeScanEvent() {
        return isEventMessage() && EventType.subscribe.toString().equalsIgnoreCase(messageBody.Event) && messageBody.EventKey != null;
    }

    public boolean isScanEvent() {
        return isEventMessage() && EventType.SCAN.toString().equalsIgnoreCase(messageBody.Event);
    }

    public boolean isLocationEvent() {
        return isEventMessage() && EventType.LOCATION.toString().equalsIgnoreCase(messageBody.Event);
    }

    public boolean isClickEvent() {
        return isEventMessage() && EventType.CLICK.toString().equalsIgnoreCase(messageBody.Event);
    }

    public boolean isViewEvent() {
        return isEventMessage() && EventType.VIEW.toString().equalsIgnoreCase(messageBody.Event);
    }

    /*******************************************************************************************************/

    /** 提供消息公共字段的get和set方法 */
    public String getFromUserName() {
        return messageBody.FromUserName;
    }

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

    public String getToUserName() {
        return messageBody.ToUserName;
    }

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

    public Long getCreateTime() {
        return messageBody.CreateTime;
    }

    public void setCreateTime(Long createTime) {
        messageBody.CreateTime = createTime;
    }

    public String getMsgType() {
        return messageBody.MsgType;
    }

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

    /** 提供protected類型的get和set方法 */

    protected String getMsgId() {
        return messageBody.MsgId;
    }

    protected void setMsgId(String msgId) {
        messageBody.MsgId = msgId;
    }

    protected String getContent() {
        return messageBody.Content;
    }

    protected void setContent(String content) {
        messageBody.Content = content;
    }

    public String getPicUrl() {
        return messageBody.PicUrl;
    }

    public void setPicUrl(String picUrl) {
        messageBody.PicUrl = picUrl;
    }

    public String getMediaId() {
        return messageBody.MediaId;
    }

    public void setMediaId(String mediaId) {
        messageBody.MediaId = mediaId;
    }

    public String getFormat() {
        return messageBody.Format;
    }

    public void setFormat(String format) {
        messageBody.Format = format;
    }

    public String getThumbMediaId() {
        return messageBody.ThumbMediaId;
    }

    public void setThumbMediaId(String thumbMediaId) {
        messageBody.ThumbMediaId = thumbMediaId;
    }

    public String getTitle() {
        return messageBody.Title;
    }

    public void setTitle(String title) {
        messageBody.Title = title;
    }

    public String getDescription() {
        return messageBody.Description;
    }

    public void setDescription(String description) {
        messageBody.Description = description;
    }

    public String getUrl() {
        return messageBody.Url;
    }

    public void setUrl(String url) {
        messageBody.Url = url;
    }

    public String getLocation_X() {
        return messageBody.Location_X;
    }

    public void setLocation_X(String location_X) {
        messageBody.Location_X = location_X;
    }

    public String getLocation_Y() {
        return messageBody.Location_Y;
    }

    public void setLocation_Y(String location_Y) {
        messageBody.Location_Y = location_Y;
    }

    public String getScale() {
        return messageBody.Scale;
    }

    public void setScale(String scale) {
        messageBody.Scale = scale;
    }

    public String getLabel() {
        return messageBody.Label;
    }

    public void setLabel(String label) {
        messageBody.Label = label;
    }

    public String getEvent() {
        return messageBody.Event;
    }

    public void setEvent(String event) {
        messageBody.Event = event;
    }

    public String getEventKey() {
        return messageBody.EventKey;
    }

    public void setEventKey(String eventKey) {
        messageBody.EventKey = eventKey;
    }

    public String getTicket() {
        return messageBody.Ticket;
    }

    public void setTicket(String ticket) {
        messageBody.Ticket = ticket;
    }

    public Double getLatitude() {
        return messageBody.Latitude;
    }

    public void setLatitude(Double latitude) {
        messageBody.Latitude = latitude;
    }

    public Double getLongitude() {
        return messageBody.Longitude;
    }

    public void setLongitude(Double longitude) {
        messageBody.Longitude = longitude;
    }

    public Double getPrecision() {
        return messageBody.Precision;
    }

    public void setPrecision(Double precision) {
        messageBody.Precision = precision;
    }

}
  • MessageBody:(真正放xml屬性的地方,之所以有這個類,具體解釋見代碼中。簡單的說,實用繼承的方式需要解析xml倆次,實用聚合方式只解析一次)
package com.yd.wechat.message.common;

/**
 * @title 這個類用於接收所有的消息。
 * @desc 經過本人考慮,多次修改,發現,很多消息類似,但也有區別。
 * @desc 1可以採用一個實體表示,會有很多冗餘屬性,而且可能會誤操作。
 * @desc (操作了不屬於當前類型的字段,這種情況會報 nullpointer 異常)
 * @desc 2也可以分開。
 * @desc 3還可以公用一部分,分開一部分。(繼承)
 * @desc 最初本人想採用3的方式,後來發現越來越多的需要提前字段的字段,於是越來越多字段要提到公用的實體中。
 * @desc 而且,每次都必須先解析爲公用實體,判斷類型之後再解析爲具體類型。
 * @desc 於是,最終修改爲採用1個實體表示。
 * @desc 但是仍然使用許多具體的實體,用於提供get和set方法,這樣控制了不同類型對不同字段的訪問權限。
 */
public class MessageBody {

    /** 每個消息都帶有的字段,在本類提供了get/set方法 */
    protected String FromUserName;
    protected String ToUserName;
    protected Long CreateTime;
    protected String MsgType;

    protected String MsgId;
    protected String Content;
    protected String PicUrl;
    protected String MediaId;
    protected String Format;
    protected String ThumbMediaId;
    protected String Title;
    protected String Description;
    protected String Url;
    protected String Event;
    protected String EventKey;
    protected String Ticket;
    protected String Location_X;
    protected String Location_Y;
    protected String Scale;
    protected String Label;
    protected Double Latitude;
    protected Double Longitude;
    protected Double Precision;

    /*******************************************************************************************************/
    /** 提供消息類型的判斷的方法 ***********************************************************************************/
    public boolean isTextMessage() {
        return MessageType.text.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isImageMessage() {
        return MessageType.image.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isVoiceMessage() {
        return MessageType.voice.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isVideoMessage() {
        return MessageType.video.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isShortVideoMessage() {
        return MessageType.shortvideo.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isLocationMessage() {
        return MessageType.location.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isLinkMessage() {
        return MessageType.link.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isEventMessage() {
        return MessageType.event.toString().equalsIgnoreCase(this.MsgType);
    }

    public boolean isSubscribeEvent() {
        return isEventMessage() && EventType.subscribe.toString().equalsIgnoreCase(this.Event) && this.EventKey == null;
    }

    public boolean isUnSubscribeEvent() {
        return isEventMessage() && EventType.unsubscribe.toString().equalsIgnoreCase(this.Event);
    }

    public boolean isSubscribeScanEvent() {
        return isEventMessage() && EventType.subscribe.toString().equalsIgnoreCase(this.Event) && this.EventKey != null;
    }

    public boolean isScanEvent() {
        return isEventMessage() && EventType.SCAN.toString().equalsIgnoreCase(this.Event);
    }

    public boolean isLocationEvent() {
        return isEventMessage() && EventType.LOCATION.toString().equalsIgnoreCase(this.Event);
    }

    public boolean isClickEvent() {
        return isEventMessage() && EventType.CLICK.toString().equalsIgnoreCase(this.Event);
    }

    public boolean isViewEvent() {
        return isEventMessage() && EventType.VIEW.toString().equalsIgnoreCase(this.Event);
    }

    /*******************************************************************************************************/

}
  • MessageType(不多說,消息類型嘛)
package com.yd.wechat.message.common;

public enum MessageType {

    text,image,voice,video,shortvideo,location,link,

    event,

    music,news

}

微信服務器發送的xml解析(weChatUtils編寫)

  • 本節的weChatUtils上一節一節貼代碼,只不過當時精簡過了,這節下面貼一個完整的。代碼中有解釋,大家仔細看都能明白的。
package com.yd.wechat.core;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.xml.bind.annotation.adapters.HexBinaryAdapter;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;
import com.yd.wechat.message.event.ClickEventMessage;
import com.yd.wechat.message.event.LocationEventMessage;
import com.yd.wechat.message.event.ScanEventMessage;
import com.yd.wechat.message.event.SubscribeEventMessage;
import com.yd.wechat.message.event.SubscribeScanEventMessage;
import com.yd.wechat.message.event.UnSubscribeEventMessage;
import com.yd.wechat.message.event.ViewEventMessage;
import com.yd.wechat.message.normal.ImageMessage;
import com.yd.wechat.message.normal.LinkMessage;
import com.yd.wechat.message.normal.LocationMessage;
import com.yd.wechat.message.normal.ShortVideoMessage;
import com.yd.wechat.message.normal.TextMessage;
import com.yd.wechat.message.normal.VideoMessage;
import com.yd.wechat.message.normal.VoiceMessage;
import com.yd.wechat.utils.XmlUtils;

public class WeChatUtils {

    private static final String token = "hello";

    public static Boolean checkSignature(String signature, String timestamp, String nonce) {
        //sort
        String[] arr = new String[] { token, timestamp, nonce };
        Arrays.sort(arr);
        StringBuffer sf = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            sf.append(arr[i]);
        }
        //sha1加密
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("SHA");
            // 執行摘要方法  
            byte[] digest = md.digest(sf.toString().getBytes());
            String encriptStr = new HexBinaryAdapter().marshal(digest);
            if (encriptStr.equalsIgnoreCase(signature)) {
                return true;
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 消息解析步驟1:
     * @param xmlContent 要解析的xml字符串
     */
    public static Message parseMessage(String xmlContent) {
        if (xmlContent == null)
            return null;
        List<Converter> converters = new ArrayList<Converter>();
        converters.add(new Converter() {
            @Override
            public boolean canConvert(Class clazz) {
                if (clazz.equals(Double.class))
                    return true;
                return false;
            }

            @Override
            public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
                if (reader.getValue() != null && !reader.getValue().isEmpty()) {
                    /** 如果不滿足條件直接返回null,如果轉換過程出現異常也直接返回null。 */
                    /** 注意這裏這麼做的原因是,Double類型轉換的時候如果是空字符串會報錯,導致整個xml轉換出錯。 */
                    try {
                        Double ret = Double.parseDouble(reader.getValue());
                        return ret;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }

            @Override
            public void marshal(Object obj, HierarchicalStreamWriter writer, MarshallingContext context) {

            }
        });
        converters.add(new Converter() {
            @Override
            public boolean canConvert(Class clazz) {
                if (clazz.equals(Long.class))
                    return true;
                return false;
            }

            @Override
            public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
                if (reader.getValue() != null && !reader.getValue().isEmpty()) {
                    /** 如果不滿足條件直接返回null,如果轉換過程出現異常也直接返回null。 */
                    /** 注意這裏這麼做的原因是,Double類型轉換的時候如果是空字符串會報錯,導致整個xml轉換出錯。 */
                    try {
                        Long ret = Long.parseLong(reader.getValue());
                        return ret;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }

            @Override
            public void marshal(Object obj, HierarchicalStreamWriter writer, MarshallingContext context) {

            }
        });
        MessageBody messageBody = XmlUtils.xml2Object(xmlContent, MessageBody.class, "xml", converters);
        if (messageBody == null)
            return null;
        return parseMessage(messageBody, xmlContent);
    }

    /***
     * 消息解析步驟2:
     * 如果能夠識別類型,則返回一個具體的類型。 否則返回原始Message即可。
     * 
     * @param messageBody 待識別的message。
     * @param xmlContent 原始xml數據。
     * @return 如果能夠識別類型,則返回一個具體的類型。 否則返回原始Message即可。
     */
    public static Message parseMessage(MessageBody messageBody, String xmlContent) {
        /** 文本消息 */
        if (messageBody.isTextMessage()) {
            return new TextMessage(messageBody);
        } else if (messageBody.isImageMessage()) {
            return new ImageMessage(messageBody);
        } else if (messageBody.isVoiceMessage()) {
            return new VoiceMessage(messageBody);
        } else if (messageBody.isVideoMessage()) {
            return new VideoMessage(messageBody);
        } else if (messageBody.isShortVideoMessage()) {
            return new ShortVideoMessage(messageBody);
        } else if (messageBody.isLocationMessage()) {
            return new LocationMessage(messageBody);
        } else if (messageBody.isLinkMessage()) {
            return new LinkMessage(messageBody);
        } else if (messageBody.isSubscribeEvent()) {
            return new SubscribeEventMessage(messageBody);
        } else if (messageBody.isUnSubscribeEvent()) {
            return new UnSubscribeEventMessage(messageBody);
        } else if (messageBody.isSubscribeScanEvent()) {
            return new SubscribeScanEventMessage(messageBody);
        } else if (messageBody.isScanEvent()) {
            return new ScanEventMessage(messageBody);
        } else if (messageBody.isLocationEvent()) {
            return new LocationEventMessage(messageBody);
        } else if (messageBody.isClickEvent()) {
            return new ClickEventMessage(messageBody);
        } else if (messageBody.isViewEvent()) {
            return new ViewEventMessage(messageBody);
        }

        /** 如果不符合任何的類型,則直接構造一個Message返回。 */
        return new Message(messageBody);
    }

}

控制器編寫

  • 依然是HelloController,不好意思,實在不喜歡精簡代碼了,部分關於回覆的是之後的內容,大家先簡單看吧,看不懂就略過以後看。
  • 還有一點注意:關於回覆消息的代碼有些註釋掉的代碼以及關於視頻回覆部分暫時還有待完善,有些問題。所以如果想學習回覆的請以後看我繼續更新吧。
@RequestMapping(value = "/accept.do", method = RequestMethod.POST)
    @ResponseBody
    public String acceptContentMessage(@RequestBody String xmlContent) {
        try {
            xmlContent = new String(xmlContent.getBytes("ISO8859-1"), "utf-8");
            System.out.println("===========>>>msg is<<<===========");
            System.out.println(xmlContent);
            System.out.println("===========>>>msg end<<<===========");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        String ans = "";

        Message message = WeChatUtils.parseMessage(xmlContent);
        if (message == null) {
            ans = "message is null";
        } else if (message.isTextMessage()) {

            TextMessage textMessage = (TextMessage) message;
            String content = textMessage.getContent();
            if ("music".equalsIgnoreCase(content)) {
                //return MusicMessage
                String musicURL = url + "res/music/test.mp3";
                String HQmusicURL = url + "res/music/test.mp3";
                System.out.println(new MusicReply(message, "title", "desc", musicURL, HQmusicURL, null).toString());
                return new MusicReply(message, "title", "desc", musicURL, HQmusicURL, null).toString();
            } else if ("news".equalsIgnoreCase(content)) {
                //return news message
                NewsReply newsReply = new NewsReply(message);
                newsReply.addNewsItem("titleA", "descriptionA", url + "res/img/icon1.png", "http://www.baidu.com");
                newsReply.addNewsItem("titleB", "descriptionB", url + "res/img/icon2.png", "http://www.baidu.com");
                newsReply.addNewsItem("titleC", "descriptionC", url + "res/img/icon3.png", "http://www.baidu.com");
                newsReply.addNewsItem("titleD", "descriptionD", url + "res/img/icon4.png", "http://www.baidu.com");
                System.out.println(newsReply.toString());
                return newsReply.toString();
            } else {
                //return textMessage
                return new TextReply(textMessage, "" + textMessage.getContent()).toString();
            }
        } else if (message.isImageMessage()) {
            ImageMessage imageMessage = (ImageMessage) message;

            System.out.println("===========>>>reply is<<<===========");
            System.out.println(new ImageReply(imageMessage, imageMessage.getMediaId()).toString());
            System.out.println("============>>>>reply end<<<===========");

            return new ImageReply(imageMessage, imageMessage.getMediaId()).toString();

        } else if (message.isVoiceMessage()) {
            VoiceMessage voiceMessage = (VoiceMessage) message;
            System.out.println("===========>>>reply is<<<===========");
            System.out.println(new VoiceReply(voiceMessage, voiceMessage.getMediaId()).toString());
            System.out.println("============>>>>reply end<<<===========");
            return new VoiceReply(voiceMessage, voiceMessage.getMediaId()).toString();
        } else if (message.isVideoMessage()) {

            VideoMessage videoMessage = (VideoMessage) message;

            System.out.println("===========>>>reply is<<<===========");

            System.out.println(new VideoReply(videoMessage, videoMessage.getMediaId(), "replyTitle", "replyDescription").toString());

            System.out.println("============>>>>reply end<<<===========");

            return new VideoReply(videoMessage, videoMessage.getMediaId(), "replyTitle", "replyDescription").toString();

            //          return "<?xml version=\"1.0\" encoding=\"ISO8859-1\"?>"+
            //          "<xml>"+
            //          "<FromUserName>gh_0d0dbff95290</FromUserName>"+
            //          "<ToUserName>oSUj2so2rsxPrDLy3IThmNd5-r8Q</ToUserName>"+
            //          "<CreateTime>1430112520511</CreateTime>"+
            //          "<MsgType>video</MsgType>"+
            //          "  <Video>"+
            //          "    <MediaId><![CDATA["+ videoMessage.getMediaId() +"]]</MediaId>"+
            //          "    <Title><![CDATA[replyTitle]]></Title>"+
            //          "    <Description>replyDescription</Description>"+
            //          "  </Video>"+
            //          "</xml>";

//                      return "<xml>"+
//                      "<ToUserName><![CDATA[oSUj2so2rsxPrDLy3IThmNd5-r8Q]]></ToUserName>"+
//                      "<FromUserName><![CDATA[gh_0d0dbff95290]]></FromUserName>"+
//                      "<CreateTime>12345678</CreateTime>"+
//                      "<MsgType><![CDATA[video]]></MsgType>"+
//                      "<Video>"+
//                      "<MediaId><![CDATA[TM6A2Prf1Q19XolT7S0gr4oduh1paHT72i0QJ6Xt0H2SkYwgSNsp-C641w-FjC1U]]></MediaId>"+
//                      "<Title><![CDATA[replyTitle]]></Title>"+
//                      "<Description><![CDATA[replyDescription]]></Description>"+
//                      "</Video> "+
//                      "</xml>";

        } else if (message.isShortVideoMessage()) {
            ShortVideoMessage shortVideoMessage = (ShortVideoMessage) message;
            ans = "this is an shortVideoMessage";
        } else if (message.isLocationMessage()) {
            LocationMessage locationMessage = (LocationMessage) message;
            ans = "this is an locationMessage";
        } else if (message.isLinkMessage()) {
            LinkMessage linkMessage = (LinkMessage) message;
            ans = "this is an linkMessage";
        }
        /** event begin */
        else if (message.isSubscribeEvent()) {
            SubscribeEventMessage subscribeMessage = (SubscribeEventMessage) message;
            ans = "this is an subscribeMessage";
        } else if (message.isUnSubscribeEvent()) {
            UnSubscribeEventMessage unSubscribeMessage = (UnSubscribeEventMessage) message;
            ans = "this is an unSubscribeMessage";
        } else if (message.isSubscribeScanEvent()) {
            SubscribeScanEventMessage subscribeScanMessage = (SubscribeScanEventMessage) message;
            ans = "this is an subscribe subscribe scan Message";
        } else if (message.isScanEvent()) {
            ScanEventMessage scanMessage = (ScanEventMessage) message;
            ans = "this is an Scan Message";
        } else if (message.isClickEvent()) {
            ClickEventMessage clickMessage = (ClickEventMessage) message;
            ans = "this is an click Message";
        } else if (message.isViewEvent()) {
            ViewEventMessage viewMessage = (ViewEventMessage) message;
            ans = "this is an view Message";
        } else {
            ans = "this is an unknown message";
        }

        return "success";
    }

    /**
     * @desc 用戶未關注時,進行關注後的事件推送
     * 
     * @param ToUserName 開發者微信號
     * @param FromUserName 發送方帳號(一個OpenID)
     * @param CreateTime 消息創建時間 (整型)
     * @param MsgType 消息類型,event
     * @param Event 事件類型,subscribe
     * @param EventKey 事件KEY值,qrscene_爲前綴,後面爲二維碼的參數值
     * @param Ticket 二維碼的ticket,可用來換取二維碼圖片
     */
    //  public void subscribe() {
    //  }
}

實體補全

  • 大家應該發現我用了好多封裝的消息實體,下面都給大家列出來:
  • TextMessage
package com.yd.wechat.message.normal;

import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;

/***
 * 文本消息
 * 
 * @author 一旦
 * @param ToUserName 開發者微信號
 * @param FromUserName 發送方帳號(一個OpenID)
 * @param CreateTime 消息創建時間 (整型)
 * @param MsgType text
 * @param Content 文本消息內容
 * @param MsgId 消息id,64位整型
 */
public class TextMessage extends Message {

    //  protected String MsgId;
    //  protected String Content;

    public TextMessage(MessageBody messageBody) {
        super(messageBody);
    }

    public String getMsgId() {
        return super.getMsgId();
    }

    public void setMsgId(String msgId) {
        super.setMsgId(msgId);
    }

    public String getContent() {
        return super.getContent();
    }

    public void setContent(String content) {
        super.setContent(content);
    }

}
  • ImageMessage
package com.yd.wechat.message.normal;

import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;

/***
 * 圖片消息
 * 
 * @param ToUserName 開發者微信號
 * @param FromUserName 發送方帳號(一個OpenID)
 * @param CreateTime 消息創建時間 (整型)
 * @param MsgType image
 * @param PicUrl 圖片鏈接
 * @param MediaId 圖片消息媒體id,可以調用多媒體文件下載接口拉取數據。
 * @param MsgId 消息id,64位整型
 * 
 */
public class ImageMessage extends Message {

//  protected String PicUrl;
//  protected String MediaId;
//  protected String MsgId;

    public ImageMessage(MessageBody messageBody) {
        super(messageBody);
    }

    public String getPicUrl() {
        return super.getPicUrl();
    }

    public void setPicUrl(String picUrl) {
        super.setPicUrl(picUrl);
    }

    public String getMediaId() {
        return super.getMediaId();
    }

    public void setMediaId(String mediaId) {
        super.setMediaId(mediaId);
    }

    public String getMsgId() {
        return super.getMsgId();
    }

    public void setMsgId(String msgId) {
        super.setMsgId(msgId);
    }

}
  • VoiceMessage
package com.yd.wechat.message.normal;

import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;

/***
 * 語音消息
 * 
 * @param ToUserName 開發者微信號
 * @param FromUserName 發送方帳號(一個OpenID)
 * @param CreateTime 消息創建時間 (整型)
 * @param MsgType 語音爲voice
 * @param MediaId 語音消息媒體id,可以調用多媒體文件下載接口拉取數據。
 * @param Format 語音格式,如amr,speex等
 * @param MsgID 消息id,64位整型
 */
public class VoiceMessage extends Message {

    //  protected String MediaId;
    //  protected String Format;
    //  protected String MsgId;

    public VoiceMessage(MessageBody messageBody) {
        super(messageBody);
    }

    public String getMediaId() {
        return super.getMediaId();
    }

    public void setMediaId(String mediaId) {
        super.setMediaId(mediaId);
    }

    public String getFormat() {
        return super.getFormat();
    }

    public void setFormat(String format) {
        super.setFormat(format);
    }

    public String getMsgId() {
        return super.getMsgId();
    }

    public void setMsgId(String msgId) {
        super.setMsgId(msgId);
    }

}
  • VideoMessage
package com.yd.wechat.message.normal;

import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;

/**
 * 視頻消息
 * 
 * @param ToUserName 開發者微信號
 * @param FromUserName 發送方帳號(一個OpenID)
 * @param CreateTime 消息創建時間 (整型)
 * @param MsgType 視頻爲video
 * @param MediaId 視頻消息媒體id,可以調用多媒體文件下載接口拉取數據。
 * @param ThumbMediaId 視頻消息縮略圖的媒體id,可以調用多媒體文件下載接口拉取數據。
 * @param MsgId 消息id,64位整型
 * 
 */
public class VideoMessage extends Message {

//  protected String MediaId;
//  protected String ThumbMediaId;
//  protected String MsgId;

    public VideoMessage(MessageBody messageBody) {
        super(messageBody);
    }

    public String getMediaId() {
        return super.getMediaId();
    }

    public void setMediaId(String mediaId) {
        super.setMediaId ( mediaId);
    }

    public String getThumbMediaId() {
        return super.getThumbMediaId();
    }

    public void setThumbMediaId(String thumbMediaId) {
        super.setThumbMediaId ( thumbMediaId);
    }

    public String getMsgId() {
        return super.getMsgId();
    }

    public void setMsgId(String msgId) {
        super.setMsgId ( msgId);
    }

}
  • ShortVideoMessage
package com.yd.wechat.message.normal;

import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;

/**
 * 小視頻消息
 * 
 * @param ToUserName 開發者微信號
 * @param FromUserName 發送方帳號(一個OpenID)
 * @param CreateTime 消息創建時間 (整型)
 * @param MsgType 小視頻爲shortvideo
 * @param MediaId 視頻消息媒體id,可以調用多媒體文件下載接口拉取數據。
 * @param ThumbMediaId 視頻消息縮略圖的媒體id,可以調用多媒體文件下載接口拉取數據。
 * @param MsgId 消息id,64位整型
 */
public class ShortVideoMessage extends Message {

    //  protected String MediaId;
    //  protected String ThumbMediaId;
    //  protected String MsgId;

    public ShortVideoMessage(MessageBody messageBody) {
        super(messageBody);
    }

    public String getMediaId() {
        return super.getMediaId();
    }

    public void setMediaId(String mediaId) {
        super.setMediaId(mediaId);
    }

    public String getThumbMediaId() {
        return super.getThumbMediaId();
    }

    public void setThumbMediaId(String thumbMediaId) {
        super.setThumbMediaId(thumbMediaId);
    }

    public String getMsgId() {
        return super.getMsgId();
    }

    public void setMsgId(String msgId) {
        super.setMsgId(msgId);
    }

}
  • LinkMessage
package com.yd.wechat.message.normal;

import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;

/**
 * 鏈接消息
 * 
 * @param ToUserName 接收方微信號
 * @param FromUserName 發送方微信號,若爲普通用戶,則是一個OpenID
 * @param CreateTime 消息創建時間
 * @param MsgType 消息類型,link
 * @param Title 消息標題
 * @param Description 消息描述
 * @param Url 消息鏈接
 * @param MsgId 消息id,64位整型
 * 
 */
public class LinkMessage extends Message {

    //  protected String Title;
    //  protected String Description;
    //  protected String Url;
    //  protected String MsgId;

    public LinkMessage(MessageBody messageBody) {
        super(messageBody);
    }

    public String getTitle() {
        return super.getTitle();
    }

    public void setTitle(String title) {
        super.setTitle(title);
    }

    public String getDescription() {
        return super.getDescription();
    }

    public void setDescription(String description) {
        super.setDescription(description);
    }

    public String getUrl() {
        return super.getUrl();
    }

    public void setUrl(String url) {
        super.setUrl(url);
    }

    public String getMsgId() {
        return super.getMsgId();
    }

    public void setMsgId(String msgId) {
        super.setMsgId(msgId);
    }

}
  • LocationMessage
package com.yd.wechat.message.normal;

import com.yd.wechat.message.common.Message;
import com.yd.wechat.message.common.MessageBody;

/***
 * 地理位置消息
 * 
 * @param ToUserName 開發者微信號
 * @param FromUserName 發送方帳號(一個OpenID)
 * @param CreateTime 消息創建時間 (整型)
 * @param MsgType location
 * @param Location_X 地理位置維度
 * @param Location_Y 地理位置經度
 * @param Scale 地圖縮放大小
 * @param Label 地理位置信息
 * @param MsgId 消息id,64位整型
 */
public class LocationMessage extends Message {

    //  protected String Location_X;
    //  protected String Location_Y;
    //  protected String Scale;
    //  protected String Label;
    //  protected String MsgId;

    public LocationMessage(MessageBody messageBody) {
        super(messageBody);
    }

    public String getLocation_X() {
        return super.getLocation_X();
    }

    public void setLocation_X(String location_X) {
        super.setLocation_X(location_X);
    }

    public String getLocation_Y() {
        return super.getLocation_Y();
    }

    public void setLocation_Y(String location_Y) {
        super.setLocation_Y(location_Y);
    }

    public String getScale() {
        return super.getScale();
    }

    public void setScale(String scale) {
        super.setScale(scale);
    }

    public String getLabel() {
        return super.getLabel();
    }

    public void setLabel(String label) {
        super.setLabel(label);
    }

    public String getMsgId() {
        return super.getMsgId();
    }

    public void setMsgId(String msgId) {
        super.setMsgId(msgId);
    }

}

總結

本節基本上完成了所有的類型的消息的接收,希望對大家有幫助。
由於個人時間有限,排版和對代碼的修剪方面做得不是很好,希望大家多多包涵。下一節再見哦。

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