目录:
- 前言
- 回顾
- 本节内容
- 准备工作
- 开发喽
- 公共部分
- 微信服务器发送的xml解析weChatUtils编写
- 控制器编写
- 实体补全
- 总结
前言
最近忙于毕业设计,更新慢,希望大家见谅。
回顾
上一节我讲了如何申请微信公众平台测试账号、配置接口信息、搭建了开发环境,并且初步实现了微信服务器消息的验证。
本节内容
- 实现了微信的消息验证之后,需要注意的是,每次微信服务器发送消息过来的时候,我们都需要进行验证,避免有不法分子冒充微信平台恶意发送消息。
- 本节将会继续讲解,主要内容是消息接收。
准备工作
- 这里我给大家列出几个工具类,这些工具类是我个人编写的,应该不是很难,所以不会讲解,只是给大家贴个代码:
- 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);
}
}
总结
本节基本上完成了所有的类型的消息的接收,希望对大家有帮助。
由于个人时间有限,排版和对代码的修剪方面做得不是很好,希望大家多多包涵。下一节再见哦。
时间: 2024-10-05 10:45:42