本例中有些引用的类与方法不做过多介绍,之后会提供完整源码下载,请自行查看。
本篇根据开发者文档-被动回复用户消息编写。请对照查看,一些传入与返回参数就不过多介绍。地址为:https://mp.weixin.qq.com/wiki/18/c66a9f0b5aa952346e46dc39de20f672.html
简述
当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。
微信服务器在将用户的消息发给公众号的开发者服务器地址(开发者中心处配置)后,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次,如果在调试中,发现用户无法收到响应的消息,可以检查是否消息处理超时。关于重试的消息排重,有msgid的消息推荐使用msgid排重。事件类型消息推荐使用FromUserName + CreateTime 排重。
如果开发者希望增强安全性,可以在开发者中心处开启消息加密,这样,用户发给公众号的消息以及公众号被动回复用户消息都会继续加密(但),详见被动回复消息加解密说明。
假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复),否则,将出现严重的错误提示。
“`
/*
* 被动回复用户消息
* http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html
*/
public class BaseRespMsg {
public static XStream xstream = XMLUtil.xstream;
private String ToUserName; // 开发者微信号
private String FromUserName; // 发送方帐号(一个OpenID)
private long CreateTime; // 消息创建时间 (整型)
private String MsgType; // 消息类型(text/image/location/link)
public String getToUserName() {
return ToUserName;
}
public void setToUserName(String toUserName) {
ToUserName = toUserName;
}
public String getFromUserName() {
return FromUserName;
}
public void setFromUserName(String fromUserName) {
FromUserName = fromUserName;
}
public long getCreateTime() {
return CreateTime;
}
public void setCreateTime(long createTime) {
CreateTime = createTime;
}
public String getMsgType() {
return MsgType;
}
public void setMsgType(String msgType) {
MsgType = msgType;
}
}
“`
回复消息类型
回复文本消息
/* * 被动回复用户消息 * http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html */ public class BaseRespMsg { public static XStream xstream = XMLUtil.xstream; private String ToUserName; // 开发者微信号 private String FromUserName; // 发送方帐号(一个OpenID) private long CreateTime; // 消息创建时间 (整型) private String MsgType; // 消息类型(text/image/location/link) public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public long getCreateTime() { return CreateTime; } public void setCreateTime(long createTime) { CreateTime = createTime; } public String getMsgType() { return MsgType; } public void setMsgType(String msgType) { MsgType = msgType; } }
回复图片消息
/* * MsgType---> * image:图片消息 */ public class ImageRespMsg extends BaseRespMsg { private List<Image> Image; public List<Image> getImage() { if(Image == null) Image = new ArrayList<Image>(); return Image; } public void setImage(List<Image> images) { Image = images; } public class Image { private String MediaId; //是 通过素材管理中的接口上传多媒体文件,得到的id public String getMediaId() { return MediaId; } public void setMediaId(String mediaId) { MediaId = mediaId; } } /* * 返回的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>12345678</CreateTime> * <MsgType><![CDATA[image]]></MsgType> * <Image> * <MediaId><![CDATA[media_id]]></MediaId> * </Image> * </xml> */ public static String responseMessage(ImageRespMsg imageMessage) { imageMessage.setCreateTime(new Date().getTime()); imageMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_IMAGE); xstream.alias("xml", imageMessage.getClass()); xstream.addImplicitCollection(imageMessage.getClass(), "Image"); xstream.alias("Image", imageMessage.new Image().getClass()); return xstream.toXML(imageMessage); } public static String test(String xmlStr) { String response = "ImageRespMsg-->error"; try { ImageReqMsg imageReqMsg = ImageReqMsg.requestMessage(xmlStr); ImageRespMsg imageRespMsg = new ImageRespMsg(); imageRespMsg.setToUserName(imageReqMsg.getFromUserName()); imageRespMsg.setFromUserName(imageReqMsg.getToUserName()); int images = 1; for(int i=0; i<images; i++) { ImageRespMsg.Image image = imageRespMsg.new Image(); image.setMediaId(imageReqMsg.getMediaId()); imageRespMsg.getImage().add(image); } response = responseMessage(imageRespMsg); } catch(Exception e) { e.printStackTrace(); } return response; } }
回复语音消息
/* * MsgType---> * voice:语音消息 */ public class VoiceRespMsg extends BaseRespMsg { private List<Voice> Voice; public List<Voice> getVoice() { if(Voice == null) Voice = new ArrayList<Voice>(); return Voice; } public void setVoice(List<Voice> voice) { Voice = voice; } public class Voice { private String MediaId; //是 通过素材管理中的接口上传多媒体文件,得到的id public String getMediaId() { return MediaId; } public void setMediaId(String mediaId) { MediaId = mediaId; } } /* * 返回的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>12345678</CreateTime> * <MsgType><![CDATA[voice]]></MsgType> * <Voice> * <MediaId><![CDATA[media_id]]></MediaId> * </Voice> * </xml> */ public static String responseMessage(VoiceRespMsg voiceMessage) { voiceMessage.setCreateTime(new Date().getTime()); voiceMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_VOICE); xstream.alias("xml", voiceMessage.getClass()); xstream.addImplicitCollection(voiceMessage.getClass(), "Voice"); xstream.alias("Voice", voiceMessage.new Voice().getClass()); return xstream.toXML(voiceMessage); } public static String test(String xmlStr) { String response = "VoiceRespMsg-->error"; try { VoiceReqMsg voiceReqMsg = VoiceReqMsg.requestMessage(xmlStr); VoiceRespMsg voiceRespMsg = new VoiceRespMsg(); voiceRespMsg.setToUserName(voiceReqMsg.getFromUserName()); voiceRespMsg.setFromUserName(voiceReqMsg.getToUserName()); int voices = 1; for(int i=0; i<voices; i++) { VoiceRespMsg.Voice voice = voiceRespMsg.new Voice(); voice.setMediaId(voiceReqMsg.getMediaID()); voiceRespMsg.getVoice().add(voice); } response = responseMessage(voiceRespMsg); } catch(Exception e) { e.printStackTrace(); } return response; } }
回复视频消息
/* * MsgType---> * video:视频消息 */ public class VideoRespMsg extends BaseRespMsg { private List<Video> Video; public List<Video> getVideo() { if(Video == null) Video = new ArrayList<Video>(); return Video; } public void setImage(List<Video> video) { Video = video; } public class Video { private String MediaId; //是 通过素材管理中的接口上传多媒体文件,得到的id private String Title; //否 视频消息的标题 private String Description; //否 视频消息的描述 public String getMediaId() { return MediaId; } public void setMediaId(String mediaId) { MediaId = mediaId; } public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return Description; } public void setDescription(String description) { Description = description; } } /* * 返回的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>12345678</CreateTime> * <MsgType><![CDATA[video]]></MsgType> * <Video> * <MediaId><![CDATA[media_id]]></MediaId> * <Title><![CDATA[title]]></Title> * <Description><![CDATA[description]]></Description> * </Video> * </xml> */ public static String responseMessage(VideoRespMsg videoMessage) { videoMessage.setCreateTime(new Date().getTime()); videoMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_VIDEO); xstream.alias("xml", videoMessage.getClass()); xstream.addImplicitCollection(videoMessage.getClass(), "Video"); xstream.alias("Video", videoMessage.new Video().getClass()); return xstream.toXML(videoMessage); } public static String test(String xmlStr) { String response = "VideoRespMsg-->error"; try { VideoReqMsg videoReqMsg = VideoReqMsg.requestMessage(xmlStr); VideoRespMsg videoRespMsg = new VideoRespMsg(); videoRespMsg.setToUserName(videoReqMsg.getFromUserName()); videoRespMsg.setFromUserName(videoReqMsg.getToUserName()); int videos = 1; for(int i=0; i<videos; i++) { VideoRespMsg.Video video = videoRespMsg.new Video(); video.setMediaId(WeChatCertificate.VIDEO_MEDIAID); video.setTitle("title"); video.setDescription("description"); videoRespMsg.getVideo().add(video); } response = responseMessage(videoRespMsg); } catch(Exception e) { e.printStackTrace(); } return response; } }
回复音乐消息
/* * MsgType---> * music:音乐消息 */ public class MusicRespMsg extends BaseRespMsg { private List<Music> Music; public List<Music> getMusic() { if(Music == null) Music = new ArrayList<Music>(); return Music; } public void setMusic(List<Music> music) { Music = music; } public class Music { private String Title; //否 音乐标题 private String Description; //否 音乐描述 private String MusicUrl; //否 音乐链接 private String HQMusicUrl; //否 高质量音乐链接,WIFI环境优先使用该链接播放音乐 private String ThumbMediaId; //是 缩略图的媒体id,通过素材管理中的接口上传多媒体文件,得到的id public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return Description; } public void setDescription(String description) { Description = description; } public String getMusicUrl() { return MusicUrl; } public void setMusicUrl(String musicURL) { MusicUrl = musicURL; } public String getHQMusicUrl() { return HQMusicUrl; } public void setHQMusicUrl(String hQMusicUrl) { HQMusicUrl = hQMusicUrl; } public String getThumbMediaId() { return ThumbMediaId; } public void setThumbMediaId(String thumbMediaId) { ThumbMediaId = thumbMediaId; } } /* * 返回的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>12345678</CreateTime> * <MsgType><![CDATA[music]]></MsgType> * <Music> * <Title><![CDATA[TITLE]]></Title> * <Description><![CDATA[DESCRIPTION]]></Description> * <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl> * <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl> * <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId> * </Music> * </xml> */ public static String responseMessage(MusicRespMsg musicMessage) { musicMessage.setCreateTime(new Date().getTime()); musicMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_MUSIC); xstream.alias("xml", musicMessage.getClass()); xstream.addImplicitCollection(musicMessage.getClass(), "Music"); xstream.alias("Music", musicMessage.new Music().getClass()); return xstream.toXML(musicMessage); } public static String test(String xmlStr) { String response = "MusicRespMsg-->error"; try { TextReqMsg textReqMsg = TextReqMsg.requestMessage(xmlStr); MusicRespMsg musicRespMsg = new MusicRespMsg(); musicRespMsg.setToUserName(textReqMsg.getFromUserName()); musicRespMsg.setFromUserName(textReqMsg.getToUserName()); int musics = 1; for(int i=0; i<musics; i++) { MusicRespMsg.Music music = musicRespMsg.new Music(); music.setTitle("残酷月光"); music.setDescription(" 林宥嘉 词:向月娥 曲:陈小霞"); music.setMusicUrl("http://wma.5282.cc/2008-11//20140226/1.mp3"); music.setHQMusicUrl("http://wma.5282.cc/2008-11//20140226/1.mp3"); musicRespMsg.getMusic().add(music); } response = responseMessage(musicRespMsg); } catch(Exception e) { e.printStackTrace(); } return response; } }
回复图文消息
/* * MsgType---> * news:图文消息 */ public class NewsRespMsg extends BaseRespMsg { private int ArticleCount; //是 图文消息个数,限制为10条以内 private List<Article> Articles; //是 多条图文消息信息,默认第一个item为大图,注意,如果图文数超过10,则将会无响应 public int getArticleCount() { return ArticleCount; } public void setArticleCount(int articleCount) { ArticleCount = articleCount; } public List<Article> getArticles() { if(Articles == null) Articles = new ArrayList<Article>(); return Articles; } public void setArticles(List<Article> articles) { Articles = articles; } public class Article{ private String Title; //否 图文消息标题 private String Description; //否 图文消息描述 private String PicUrl; //否 图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 private String Url; //否 点击图文消息跳转链接 public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return Description; } public void setDescription(String description) { Description = description; } public String getPicUrl() { return PicUrl; } public void setPicUrl(String picUrl) { PicUrl = picUrl; } public String getUrl() { return Url; } public void setUrl(String url) { Url = url; } } /* * 返回的文本示例 * <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>12345678</CreateTime> * <MsgType><![CDATA[news]]></MsgType> * <ArticleCount>2</ArticleCount> * <Articles> * <item> * <Title><![CDATA[title1]]></Title> * <Description><![CDATA[description1]]></Description> * <PicUrl><![CDATA[picurl]]></PicUrl> * <Url><![CDATA[url]]></Url> * </item> * <item> * <Title><![CDATA[title]]></Title> * <Description><![CDATA[description]]></Description> * <PicUrl><![CDATA[picurl]]></PicUrl> * <Url><![CDATA[url]]></Url> * </item> * </Articles> * </xml> */ public static String responseMessage(NewsRespMsg newsMessage) { newsMessage.setCreateTime(new Date().getTime()); newsMessage.setMsgType(WeChatEntitiesType.RESP_MESSAGE_TYPE_NEWS); xstream.alias("xml", newsMessage.getClass()); xstream.alias("item", newsMessage.new Article().getClass()); return xstream.toXML(newsMessage); } public static String test(String xmlStr) { String response = "NewsRespMsg-->error"; try { TextReqMsg textReqMsg = TextReqMsg.requestMessage(xmlStr); NewsRespMsg newsRespMsg = new NewsRespMsg(); newsRespMsg.setToUserName(textReqMsg.getFromUserName()); newsRespMsg.setFromUserName(textReqMsg.getToUserName()); int articleCount = 3; newsRespMsg.setArticleCount(articleCount); for(int i=0; i<articleCount; i++) { NewsRespMsg.Article articla = newsRespMsg.new Article(); articla.setTitle("title"+i); articla.setDescription("description"+i); articla.setPicUrl("http://img5.imgtn.bdimg.com/it/u=1938623644,625001929&fm=11&gp=0.jpg"); articla.setUrl("http://www.baidu.com"); newsRespMsg.getArticles().add(articla); } response = responseMessage(newsRespMsg); } catch(Exception e) { e.printStackTrace(); } return response; } }