微信消息管理分为接收普通消息、接收事件推送、发送消息(被动回复)、客服消息、群发消息、模板消息这几部分
一、接收普通消息
当普通微信用户向公众账号发消息时,微信服务器将post消息的xml数据包到开发者填写的url上。
关于msgid,官方给出解释,相当于每个消息id,关于重试的消息排重,推荐使用msgid排重。微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。
比如文本消息的xml示例
1
2
3
4
5
6
7
8
|
<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime> 1348831860 </createtime>
<msgtype><![cdata[text]]></msgtype>
<content><![cdata[ this is a test]]></content>
<msgid> 1234567890123456 </msgid>
</xml>
|
其他的消息去官方文档查看,简单封装如下
消息抽象基类abstractmsg.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package com.phil.wechat.msg.model.req;
import java.io.serializable;
/**
* 基础消息类
*
* @author phil
*
*/
public abstract class abstractmsg implements serializable {
private static final long serialversionuid = -6244277633057415731l;
private string tousername; // 开发者微信号
private string fromusername; // 发送方帐号(一个openid)
private string msgtype = setmsgtype(); // 消息类型 例如 /text/image
private long createtime; // 消息创建时间 (整型)
private long msgid; // 消息id,64位整型
/**
* 消息类型
*
* @return
*/
public abstract string setmsgtype();
}
|
文本消息textmsg.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package com.phil.wechat.msg.model.req;
/**
* 文本消息
* @author phil
* @date 2017年6月30日
*
*/
public class textmsg extends abstractmsg {
private static final long serialversionuid = -1764016801417503409l;
private string content; // 文本消息
@override
public string setmsgtype() {
return "text" ;
}
}
|
其他的依样画葫芦......
二、被动回复用户消息
微信服务器在将用户的消息发给公众号的开发者服务器地址(开发者中心处配置)后,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次,如果在调试中,发现用户无法收到响应的消息,可以检查是否消息处理超时。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
如果出现“该公众号暂时无法提供服务,请稍后再试”,原因有两个
- 开发者在5秒内未回复任何内容
- 开发者回复了异常数据
比如回复的文本消息xml示例
1
2
3
4
5
6
7
|
<xml>
<tousername><![cdata[touser]]></tousername>
<fromusername><![cdata[fromuser]]></fromusername>
<createtime> 12345678 </createtime>
<msgtype><![cdata[text]]></msgtype>
<content><![cdata[你好]]></content>
</xml>
|
简单封装下
回复消息抽象基类respabstractmsg.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.phil.wechat.msg.model.resp;
import java.io.serializable;
/**
* 消息基类(公众帐号 -> 普通用户)
*
* @author phil
*
*/
public abstract class respabstractmsg{
// 接收方帐号(收到的openid)
private string tousername;
// 开发者微信号
private string fromusername;
// 消息创建时间 (整型)
private long createtime;
// 消息类型(text/music/news)
private string msgtype = setmsgtype(); // 消息类型
public abstract string setmsgtype();
}
|
回复文本消息resptextmsg.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package com.phil.wechat.msg.model.resp;
/**
* 回复图片消息
*
* @author phil
* @data 2017年3月26日
*
*/
public class respimagemsg extends respabstractmsg {
private image image;
@override
public string setmsgtype() {
return "image" ;
}
/**
*
* @author phil
* @date 2017年7月19日
*
*/
public class image {
// 通过素材管理中的接口上传多媒体文件,得到的id。
private string mediaid;
public string getmediaid() {
return mediaid;
}
public void setmediaid(string mediaid) {
mediaid = mediaid;
}
}
}
|
其他消息类型依样画葫芦......
三、消息的处理
掌握xml解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
|
package com.phil.wechat.msg.controller;
import java.io.ioexception;
import java.io.inputstream;
import java.util.map;
import java.util.objects;
import org.apache.commons.lang3.stringutils;
import org.dom4j.documentexception;
import org.slf4j.logger;
import org.slf4j.loggerfactory;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.controller;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.requestmethod;
import com.phil.modules.config.wechatconfig;
import com.phil.modules.util.msgutil;
import com.phil.modules.util.signatureutil;
import com.phil.modules.util.xmlutil;
import com.phil.wechat.base.controller.basecontroller;
import com.phil.wechat.base.result.wechatresult;
import com.phil.wechat.msg.model.req.basicmsg;
import com.phil.wechat.msg.model.resp.respabstractmsg;
import com.phil.wechat.msg.model.resp.respnewsmsg;
import com.phil.wechat.msg.service.wechatmsgservice;
/**
* @author phil
* @date 2017年9月19日
*
*/
@controller
@requestmapping ( "/wechat" )
public class wechatmsgcontroller extends basecontroller {
private logger logger = loggerfactory.getlogger( this .getclass());
@autowired
private wechatmsgservice wechatmsgservice;
/**
* 校验信息是否是从微信服务器发出,处理消息
* @param out
* @throws ioexception
*/
@requestmapping (value = "/handler" , method = { requestmethod.get, requestmethod.post })
public void processpost() throws exception {
this .getrequest().setcharacterencoding( "utf-8" );
this .getresponse().setcharacterencoding( "utf-8" );
boolean ispost = objects.equals( "post" , this .getrequest().getmethod().touppercase());
if (ispost) {
logger.debug( "接入成功,正在处理逻辑" );
string respxml = defaultmsgdispose( this .getrequest().getinputstream()); //processrequest(request, response);
if (stringutils.isnotblank(respxml)) {
this .getresponse().getwriter().write(respxml);
}
} else {
string signature = this .getrequest().getparameter( "signature" );
// 时间戳
string timestamp = this .getrequest().getparameter( "timestamp" );
// 随机数
string nonce = this .getrequest().getparameter( "nonce" );
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (signatureutil.checksignature(signature, timestamp, nonce)) {
// 随机字符串
string echostr = this .getrequest().getparameter( "echostr" );
logger.debug( "接入成功,echostr {}" , echostr);
this .getresponse().getwriter().write(echostr);
}
}
}
/**
* 默认处理方法
* @param input
* @return
* @throws exception
* @throws documentexception
*/
private string defaultmsgdispose(inputstream inputstream) throws exception {
string result = null ;
if (inputstream != null ) {
map<string, string> params = xmlutil.parsestreamtomap(inputstream);
if (params != null && params.size() > 0 ) {
basicmsg msginfo = new basicmsg();
string createtime = params.get( "createtime" );
string msgid = params.get( "msgid" );
msginfo.setcreatetime((createtime != null && ! "" .equals(createtime)) ? integer.parseint(createtime) : 0 );
msginfo.setfromusername(params.get( "fromusername" ));
msginfo.setmsgid((msgid != null && ! "" .equals(msgid)) ? long .parselong(msgid) : 0 );
msginfo.settousername(params.get( "tousername" ));
wechatresult resultobj = corehandler(msginfo, params);
if (resultobj == null ){ //
return null ;
}
boolean success = resultobj.issuccess(); //如果 为true,则表示返回xml文件, 直接转换即可,否则按类型
if (success) {
result = resultobj.getobject().tostring();
} else {
int type = resultobj.gettype(); // 这里规定 1 图文消息 否则直接转换
if (type == wechatresult.newsmsg) {
respnewsmsg newsmsg = (respnewsmsg) resultobj.getobject();
result = msgutil.newsmsgtoxml(newsmsg);
} else {
respabstractmsg basicmsg = (respabstractmsg) resultobj.getobject();
result = msgutil.msgtoxml(basicmsg);
}
}
} else {
result = "msg is wrong" ;
}
}
return result;
}
/**
* 核心处理
*
* @param msg
* 消息基类
* @param params
* xml 解析出来的 数据
* @return
*/
private wechatresult corehandler(basicmsg msg, map<string, string> params) {
wechatresult result = null ;
string msgtype = params.get( "msgtype" );
if (stringutils.isempty(msgtype)) {
switch (msgtype) {
case wechatconfig.req_message_type_text: // 文本消息
result = wechatmsgservice.textmsg(msg, params);
break ;
case wechatconfig.req_message_type_image: // 图片消息
result = wechatmsgservice.imagemsg(msg, params);
break ;
case wechatconfig.req_message_type_link: // 链接消息
result = wechatmsgservice.linkmsg(msg, params);
break ;
case wechatconfig.req_message_type_location: // 地理位置
result = wechatmsgservice.locationmsg(msg, params);
break ;
case wechatconfig.req_message_type_voice: // 音频消息
result = wechatmsgservice.voicemsg(msg, params);
break ;
case wechatconfig.req_message_type_shortvideo: // 短视频消息
result = wechatmsgservice.shortvideo(msg, params);
break ;
case wechatconfig.req_message_type_video: // 视频消息
result = wechatmsgservice.videomsg(msg, params);
break ;
case wechatconfig.req_message_type_event: // 事件消息
string eventtype = params.get( "event" ); //
if (eventtype != null && ! "" .equals(eventtype)) {
switch (eventtype) {
case wechatconfig.event_type_subscribe:
result = wechatmsgservice.subscribe(msg, params);
break ;
case wechatconfig.event_type_unsubscribe:
result = wechatmsgservice.unsubscribe(msg, params);
break ;
case wechatconfig.event_type_scan:
result = wechatmsgservice.scan(msg, params);
break ;
case wechatconfig.event_type_location:
result = wechatmsgservice.eventlocation(msg, params);
break ;
case wechatconfig.event_type_click:
result = wechatmsgservice.eventclick(msg, params);
break ;
case wechatconfig.event_type_view:
result = wechatmsgservice.eventview(msg, params);
break ;
case wechatconfig.kf_create_session:
result = wechatmsgservice.kfcreatesession(msg, params);
break ;
case wechatconfig.kf_close_session:
result = wechatmsgservice.kfclosesession(msg, params);
break ;
case wechatconfig.kf_switch_session:
result = wechatmsgservice.kfswitchsession(msg, params);
break ;
default :
wechatmsgservice.eventdefaultreply(msg, params);
break ;
}
}
break ;
default :
wechatmsgservice.defaultmsg(msg, params);
}
}
return result;
}
}
|
只是提供个思路,如若参考代码请移步
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/phil_jing/article/details/76358261