微信公众号开发之回复用户消息(四)
<h2 id="官方文档">官方文档</h2><p><img src="https://img2022.cnblogs.com/blog/1898315/202201/1898315-20220126011955943-1556318772.png" alt="" loading="lazy"></p>
<h2 id="返回xml格式的消息体">返回xml格式的消息体</h2>
<blockquote>
<p>回复文本消息</p>
</blockquote>
<pre><code class="language-xml"><xml>
<ToUserName><!]></ToUserName>
<FromUserName><!]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><!]></MsgType>
<Content><!]></Content>
</xml>
</code></pre>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>ToUserName</td>
<td>是</td>
<td>接收方帐号(收到的OpenID)</td>
</tr>
<tr>
<td>FromUserName</td>
<td>是</td>
<td>开发者微信号</td>
</tr>
<tr>
<td>CreateTime</td>
<td>是</td>
<td>消息创建时间 (整型)</td>
</tr>
<tr>
<td>MsgType</td>
<td>是</td>
<td>消息类型,文本为text</td>
</tr>
<tr>
<td>Content</td>
<td>是</td>
<td>回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)</td>
</tr>
</tbody>
</table>
<blockquote>
<p>回复图片消息</p>
</blockquote>
<pre><code class="language-xml"><xml>
<ToUserName><!]></ToUserName>
<FromUserName><!]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><!]></MsgType>
<Image>
<MediaId><!]></MediaId>
</Image>
</xml>
</code></pre>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>ToUserName</td>
<td>是</td>
<td>接收方帐号(收到的OpenID)</td>
</tr>
<tr>
<td>FromUserName</td>
<td>是</td>
<td>开发者微信号</td>
</tr>
<tr>
<td>CreateTime</td>
<td>是</td>
<td>消息创建时间 (整型)</td>
</tr>
<tr>
<td>MsgType 是</td>
<td>消息类型,图片为image</td>
<td></td>
</tr>
<tr>
<td>MediaId 是</td>
<td>通过素材管理中的接口上传多媒体文件,得到的id。</td>
<td></td>
</tr>
</tbody>
</table>
<pre><code class="language-xml"><xml>
<ToUserName><!]></ToUserName>
<FromUserName><!]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><!]></MsgType>
<Voice>
<MediaId><!]></MediaId>
</Voice>
</xml>
</code></pre>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>ToUserName</td>
<td>是</td>
<td>接收方帐号(收到的OpenID)</td>
</tr>
<tr>
<td>FromUserName</td>
<td>是</td>
<td>开发者微信号</td>
</tr>
<tr>
<td>CreateTime</td>
<td>是</td>
<td>消息创建时间戳 (整型)</td>
</tr>
<tr>
<td>MsgType</td>
<td>是</td>
<td>消息类型,语音为voice</td>
</tr>
<tr>
<td>MediaId</td>
<td>是</td>
<td>通过素材管理中的接口上传多媒体文件,得到的id</td>
</tr>
</tbody>
</table>
<blockquote>
<p>回复视频消息</p>
</blockquote>
<pre><code class="language-xml"><xml>
<ToUserName><!]></ToUserName>
<FromUserName><!]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><!]></MsgType>
<Video>
<MediaId><!]></MediaId>
<Title><!]></Title>
<Description><!]></Description>
</Video>
</xml>
</code></pre>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>ToUserName</td>
<td>是</td>
<td>接收方帐号(收到的OpenID)</td>
</tr>
<tr>
<td>FromUserName</td>
<td>是</td>
<td>开发者微信号</td>
</tr>
<tr>
<td>CreateTime</td>
<td>是</td>
<td>消息创建时间 (整型)</td>
</tr>
<tr>
<td>MsgType</td>
<td>是</td>
<td>消息类型,视频为video</td>
</tr>
<tr>
<td>MediaId</td>
<td>是</td>
<td>通过素材管理中的接口上传多媒体文件,得到的id</td>
</tr>
<tr>
<td>Title</td>
<td>否</td>
<td>视频消息的标题</td>
</tr>
<tr>
<td>Description</td>
<td>否</td>
<td>视频消息的描述</td>
</tr>
</tbody>
</table>
<blockquote>
<p>回复音乐消息</p>
</blockquote>
<pre><code class="language-xml"><xml>
<ToUserName><!]></ToUserName>
<FromUserName><!]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><!]></MsgType>
<Music>
<Title><!]></Title>
<Description><!]></Description>
<MusicUrl><!]></MusicUrl>
<HQMusicUrl><!]></HQMusicUrl>
<ThumbMediaId><!]></ThumbMediaId>
</Music>
</xml>
</code></pre>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>ToUserName</td>
<td>是</td>
<td>接收方帐号(收到的OpenID)</td>
</tr>
<tr>
<td>FromUserName</td>
<td>是</td>
<td>开发者微信号</td>
</tr>
<tr>
<td>CreateTime</td>
<td>是</td>
<td>消息创建时间 (整型)</td>
</tr>
<tr>
<td>MsgType</td>
<td>是</td>
<td>消息类型,音乐为music</td>
</tr>
<tr>
<td>Title</td>
<td>否</td>
<td>音乐标题</td>
</tr>
<tr>
<td>Description</td>
<td>否</td>
<td>音乐描述</td>
</tr>
<tr>
<td>MusicURL</td>
<td>否</td>
<td>音乐链接</td>
</tr>
<tr>
<td>HQMusicUrl</td>
<td>否</td>
<td>高质量音乐链接,WIFI环境优先使用该链接播放音乐</td>
</tr>
<tr>
<td>ThumbMediaId</td>
<td>是</td>
<td>缩略图的媒体id,通过素材管理中的接口上传多媒体文件,得到的id</td>
</tr>
</tbody>
</table>
<blockquote>
<p>回复图文消息</p>
</blockquote>
<pre><code class="language-xml"><xml>
<ToUserName><!]></ToUserName>
<FromUserName><!]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><!]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><!]></Title>
<Description><!]></Description>
<PicUrl><!]></PicUrl>
<Url><!]></Url>
</item>
</Articles>
</xml>
</code></pre>
<blockquote>
<p>回复图文消息</p>
</blockquote>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>ToUserName</td>
<td>是</td>
<td>接收方帐号(收到的OpenID)</td>
</tr>
<tr>
<td>FromUserName</td>
<td>是</td>
<td>开发者微信号</td>
</tr>
<tr>
<td>CreateTime</td>
<td>是</td>
<td>消息创建时间 (整型)</td>
</tr>
<tr>
<td>MsgType</td>
<td>是</td>
<td>消息类型,图文为news</td>
</tr>
<tr>
<td>ArticleCount</td>
<td>是</td>
<td>图文消息个数;当用户发送文本、图片、语音、视频、图文、地理位置这六种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息</td>
</tr>
<tr>
<td>Articles</td>
<td>是</td>
<td>图文消息信息,注意,如果图文数超过限制,则将只发限制内的条数</td>
</tr>
<tr>
<td>Title</td>
<td>是</td>
<td>图文消息标题</td>
</tr>
<tr>
<td>Description</td>
<td>是</td>
<td>图文消息描述</td>
</tr>
<tr>
<td>PicUrl</td>
<td>是</td>
<td>图片链接,支持JPG、PNG格式,较好的效果为大图360<em>200,小图200</em>200</td>
</tr>
<tr>
<td>Url</td>
<td>是</td>
<td>点击图文消息跳转链接</td>
</tr>
</tbody>
</table>
<h2 id="把这六大基础消息转成实体类">把这六大基础消息转成实体类</h2>
<blockquote>
<p>这六个消息体都有四个共同的参数</p>
</blockquote>
<table>
<thead>
<tr>
<th>参数</th>
<th>是否必须</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>ToUserName</td>
<td>是</td>
<td>接收方帐号(收到的OpenID)</td>
</tr>
<tr>
<td>FromUserName</td>
<td>是</td>
<td>开发者微信号</td>
</tr>
<tr>
<td>CreateTime</td>
<td>是</td>
<td>消息创建时间 (整型)</td>
</tr>
<tr>
<td>MsgType</td>
<td>是</td>
<td>消息类型,文本为text 图片为image 语音为voice 视频为video 音乐为music 图文为news</td>
</tr>
</tbody>
</table>
<p>只需要在每次进来的时候获取到msgTye对比用户发的消息携带的msgType是那种类型,然后进行一个回复即可</p>
<h3 id="封装父类实体类">封装父类实体类</h3>
<blockquote>
<p>六个基础消息类就可以继承父类,这里使用Java原生自带的实体类转xml的注解</p>
</blockquote>
<p>具体可参考</p>
<pre><code class="language-java">@Data
public class BaseMessage {
@XmlElement(name = "ToUserName")
private String toUserName;
@XmlElement(name = "FromUserName")
private String fromUserName;
@XmlElement(name = "CreateTime")
private String createTime;
@XmlElement(name = "MsgType")
private String msgType;
public BaseMessage() {
}
public BaseMessage(Map<String,String> requestMap) {
this.toUserName = requestMap.get("FromUserName");
this.fromUserName = requestMap.get("ToUserName");
this.createTime = System.currentTimeMillis()/1000+"";
}
public String getToUserName() {
return toUserName;
}
@XmlTransient
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getFromUserName() {
return fromUserName;
}
@XmlTransient
public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}
public String getCreateTime() {
return createTime;
}
@XmlTransient
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getMsgType() {
return msgType;
}
@XmlTransient
public void setMsgType(String msgType) {
this.msgType = msgType;
}
}
</code></pre>
<h3 id="文本类">文本类</h3>
<pre><code class="language-java">@XmlRootElement(name = "xml")
public class TextMessage extends BaseMessage{
@XmlElement(name = "Content")
private String content;
public String getContent() {
return content;
}
@XmlTransient
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "TextMessage{" +
"content='" + content + '\'' +
"toUserName='" + getToUserName() + '\'' +
", fromUserName='" + getFromUserName() + '\'' +
", createTime='" + getCreateTime() + '\'' +
'}';
}
public TextMessage() {
}
public TextMessage(Map<String,String> requestMap, String content) {
super(requestMap);
this.setMsgType("text");
this.content = content;
}
}
</code></pre>
<h3 id="图片">图片</h3>
<blockquote>
<p>图片xml里面还有包含一个子节点,需要再定义一个Image 类</p>
</blockquote>
<pre><code class="language-java">@XmlRootElement(name = "xml")
public class ImageMessage extends BaseMessage{
@XmlElement(name = "Image")
private Image image;
public Image getImage() {
return image;
}
@XmlTransient
public void setImage(Image image) {
this.image = image;
}
public ImageMessage() {
}
public ImageMessage(Map<String, String> requestMap, Image image) {
super(requestMap);
setMsgType("image");
this.image = image;
}
@Override
public String toString() {
return "ImageMessage{" +
"image=" + image +
'}';
}
}
</code></pre>
<pre><code class="language-java">public class Image {
@XmlElement(name = "MediaId")
private String mediaId;
public String getMediaId() {
return mediaId;
}
@XmlTransient
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public Image() {
}
public Image(String mediaId) {
this.mediaId = mediaId;
}
@Override
public String toString() {
return "Image{" +
"mediaId='" + mediaId + '\'' +
'}';
}
}
</code></pre>
<h3 id="视频">视频</h3>
<blockquote>
<p>视频xml里面还有包含一个子节点,需要再定义一个Video 类</p>
</blockquote>
<pre><code class="language-java">@XmlRootElement(name = "xml")
public class VideoMessage extends BaseMessage{
@XmlElement(name = "Video")
private Video video;
public VideoMessage() {
}
public VideoMessage(Map<String, String> requestMap, Video video) {
super(requestMap);
setMsgType("video");
this.video = video;
}
public Video getVideo() {
return video;
}
@XmlTransient
public void setVideo(Video video) {
this.video = video;
}
@Override
public String toString() {
return "VideoMessage{" +
"video=" + video +
'}';
}
}
</code></pre>
<pre><code class="language-java">public class Video {
@XmlElement(name = "MediaId")
private String mediaId;
@XmlElement(name = "Title")
private String title;
@XmlElement(name = "Description")
private String description;
public Video() {
}
public Video(String mediaId, String title, String description) {
this.mediaId = mediaId;
this.title = title;
this.description = description;
}
public String getMediaId() {
return mediaId;
}
@XmlTransient
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public String getTitle() {
return title;
}
@XmlTransient
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
@XmlTransient
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Video{" +
"mediaId='" + mediaId + '\'' +
", title='" + title + '\'' +
", description='" + description + '\'' +
'}';
}
}
</code></pre>
<h3 id="语音">语音</h3>
<blockquote>
<p>语音xml里面还有包含一个子节点,需要再定义一个Voice 类</p>
</blockquote>
<pre><code class="language-java">@XmlRootElement(name = "xml")
public class VoiceMessage extends BaseMessage{
@XmlElement(name = "Voice")
private Voice voice;
public VoiceMessage() {
}
public VoiceMessage(Map<String, String> requestMap, Voice voice) {
super(requestMap);
setMsgType("voice");
this.voice = voice;
}
public Voice getVoice() {
return voice;
}
public void setVoice(Voice voice) {
this.voice = voice;
}
@Override
public String toString() {
return "VoiceMessage{" +
"voice=" + voice +
'}';
}
}
</code></pre>
<pre><code class="language-java">public class Voice {
@XmlElement(name = "MediaId")
private String mediaId;
public String getMediaId() {
return mediaId;
}
@XmlTransient
public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}
public Voice() {
}
public Voice(String mediaId) {
this.mediaId = mediaId;
}
@Override
public String toString() {
return "Voice{" +
"mediaId='" + mediaId + '\'' +
'}';
}
}
</code></pre>
<h3 id="图文">图文</h3>
<blockquote>
<p>在新建的Articles实体类需要再定义一个Item类</p>
</blockquote>
<pre><code class="language-java">@XmlRootElement(name = "xml")
public class NewsInfoMessage extends BaseMessage {
@XmlElement(name = "ArticleCount")
private String articleCount;
@XmlElement(name = "Articles")
@XmlElementWrapper(name = "Articles")
private List<Articles> articles;
public NewsInfoMessage() {
}
public NewsInfoMessage(Map<String, String> requestMap, String articleCount, List<Articles> articles) {
super(requestMap);
setMsgType("news");
this.articleCount = articleCount;
this.articles = articles;
}
public String getArticleCount() {
return articleCount;
}
@XmlTransient
public void setArticleCount(String articleCount) {
this.articleCount = articleCount;
}
public List<Articles> getArticles() {
return articles;
}
@XmlTransient
public void setArticles(List<Articles> articles) {
this.articles = articles;
}
@Override
public String toString() {
return "NewsInfoMessage{" +
"articleCount='" + articleCount + '\'' +
", articles=" + articles +
'}';
}
}
</code></pre>
<pre><code class="language-java">public class Articles {
@XmlElement(name = "Item")
private Item item;
public Articles(Item item) {
this.item = item;
}
public Articles() {
}
public Item getItem() {
return item;
}
@XmlTransient
public void setItem(Item item) {
this.item = item;
}
@Override
public String toString() {
return "Articles{" +
"item=" + item +
'}';
}
}
</code></pre>
<pre><code class="language-java">public class Item {
@XmlElement(name = "title")
private String title;
@XmlElement(name = "Description")
private String description;
@XmlElement(name = "PicUrl")
private String picUrl;
@XmlElement(name = "Url")
private String url;
public Item() {
}
public Item(String title, String description, String picUrl, String url) {
this.title = title;
this.description = description;
this.picUrl = picUrl;
this.url = url;
}
public String getTitle() {
return title;
}
@XmlTransient
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
@XmlTransient
public void setDescription(String description) {
this.description = description;
}
public String getPicUrl() {
return picUrl;
}
@XmlTransient
public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}
public String getUrl() {
return url;
}
@XmlTransient
public void setUrl(String url) {
this.url = url;
}
@Override
public String toString() {
return "Item{" +
"title='" + title + '\'' +
", description='" + description + '\'' +
", picUrl='" + picUrl + '\'' +
", url='" + url + '\'' +
'}';
}
}
</code></pre>
<h3 id="注意这里的item会有几个所以在运行的时候会报错">注意这里的Item会有几个所以在运行的时候会报错</h3>
<p>只需要加set方法上一个注解</p>
<pre><code class="language-java">@XmlTransient
</code></pre>
<h2 id="使用jdk自带的jaxb进行实体类与xml的相互转换工具类">使用JDK自带的JAXB进行实体类与XML的相互转换工具类</h2>
<pre><code class="language-java">import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import java.io.IOException;
import java.io.StringWriter;
/**
* @PackageName : com.rzk.util
* @FileName : BeanToXml
* @Description :
* @Author : rzk
* @CreateTime : 24/1/2022 上午1:43
* @Version : v1.0
*/
public class BeanToXml {
private static Logger logger = LoggerFactory.getLogger(BeanToXml.class)
/**
* 对象转XML
* @param obj 目标对象
* @return返回string格式的xml报文
*/
public static String objToXml(Object obj){
StringWriter sw = new StringWriter();
String result = null;
try {
//通过传入的类,创建该类的转换上下文
JAXBContext context = JAXBContext.newInstance(obj.getClass());
//创建实例
Marshaller marshaller = context.createMarshaller();
//格式化xml输出的格式,true会格式化输出,false会全部压缩到一起=
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
//是否打印xml的说明头 <?xml version="1.0" encoding="UTF-8" standalone="yes">
//设置为true表示不打印,设置为false表示打印,默认打印
marshaller.setProperty(Marshaller.JAXB_FRAGMENT,Boolean.TRUE);
//将对象转换成输出流形式的xml
marshaller.marshal(obj,sw);
result = sw.toString() ;
} catch (JAXBException e) {
logger.error("对象转XML异常:{}",e.getMessage());
e.printStackTrace();
}finally {
try {
sw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
}
</code></pre>
<h2 id="用于处理所有的事件和消息的回复service">用于处理所有的事件和消息的回复service</h2>
<pre><code class="language-java">@Service
public class WxService {
private Logger logger = LoggerFactory.getLogger(WxService.class);
@Resource
private ReplyMessageService replyMessageService;
/**
* 用于处理所有的事件和消息的回复
* @param requestMap
* @return
*/
public String getResponse(Map<String, String> requestMap) {
BaseMessage message = null;
String msgType = requestMap.get("MsgType");
logger.info("消息类型{}:"+msgType);
//根据自己所需要的场景进行 回复相对于的消息内容
switch (msgType){
case "text":
logger.info("进入text");
message = replyMessageService.replyTextMessage(requestMap);
logger.info("进入text");
break;
case "image":
break;
case "voice":
break;
case "video":
break;
case "shortvideo":
break;
case "location":
break;
case "link":
break;
default:
break;
}
if (message!=null){
logger.info("消息======>{}:"+message);
logger.info("消息======>{}:"+BeanToXml.objToXml(message));
return BeanToXml.objToXml(message);
}
return null;
}
}
</code></pre>
<h2 id="处理回复消息类">处理回复消息类</h2>
<pre><code class="language-java">/**
* @PackageName : com.rzk.service
* @FileName : ReplyMessageService
* @Description : 处理回复消息
* @Author : rzk
* @CreateTime : 24/1/2022 上午1:50
* @Version : v1.0
*/
@Service
public class ReplyMessageService {
private Logger logger = LoggerFactory.getLogger(ReplyMessageService.class);
public BaseMessage replyTextMessage(Map<String, String> requestMap) {
logger.info("处理回复文本消息"+requestMap);
TextMessage textMessage = new TextMessage(requestMap, "hh");
logger.info("返回回复文本消息"+textMessage);
return textMessage;
}
}
</code></pre>
<h2 id="现在就控制器返回给微信公众号服务器类">现在就控制器返回给微信公众号服务器类</h2>
<blockquote>
<p>返回消息是post请求</p>
</blockquote>
<pre><code class="language-java"> @PostMapping(value = "validate")
public String validate(HttpServletRequest httpServletRequest) {
logger.info("接收到的消息{}:"+httpServletRequest);
// xml格式的消息数据
String respXml = null;
// 默认返回的文本消息内容
String respContent;
try {
// 调用parseXml方法解析请求消息
Map<String,String> requestMap = MsgUtil.parseXml(httpServletRequest);
respContent = wxService.getResponse(requestMap);
// 消息类型
logger.info("controller======>{}"+respContent);
return respContent;
} catch (Exception e) {
e.printStackTrace();
}
logger.info("controller======>{}"+respXml);
return "";
}
</code></pre>
<h2 id="效果">效果</h2>
<p><img src="https://img2022.cnblogs.com/blog/1898315/202201/1898315-20220126023129333-1865075779.gif" alt="" loading="lazy"></p><br><br>
来源:https://www.cnblogs.com/rzkwz/p/15845233.html
頁:
[1]