本文主要实现的功能包括
- 关注/取消关注事件
阅读本文之前请先认真阅读微信公众号技术文档之接受事件推送
需注意的是:验证消息的确来自微信服务器和接收事件时微信服务器都会发送请求到填写的服务器地址URL上,也就是同一个URL,区别在于请求方式不同:
-
验证消息的确来自微信服务器(具体实现可参考微信公众号开发-----验证消息的确来自微信服务器(明文模式下),开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上
-
接收普通事件推送和接收消息事件推送,微信服务器将POST消息的XML数据包到开发者填写的URL上
**
关注/取消关注事件
**
用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑。
微信服务器推送的数据如图:

根据消息类型MsgType为event以及事件类型Event为subscribe和unsubscribe来确定该推送消息属于关注/取消关注事件
实现步骤:
- 常量类
public class WechartConst {
/**
* 消息类型
*/
public class MsgType {
public static final String TEXT = "text";
public static final String EVENT = "event";
}
/**
* 事件类型
*/
public class Event {
public static final String SUBSCRIBE = "subscribe";//订阅事件
public static final String UNSUBSCRIBE = "unsubscribe";//取消订阅事件
}
}
- xml工具类
/**
* xml处理工具类
*/
public class XmlUtil {
/**
* xml转map
*/
public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException {
HashMap<String, String> map = new HashMap<String,String>();
SAXReader reader = new SAXReader();
InputStream ins = request.getInputStream();
Document doc = reader.read(ins);
Element root = doc.getRootElement();
@SuppressWarnings("unchecked")
List<Element> list = (List<Element>)root.elements();
for(Element e:list){
map.put(e.getName(), e.getText());
}
ins.close();
return map;
}
}
- 事件推送处理
public class EntryController extends Controller {
public void accept() throws IOException {
String method = getRequest().getMethod();
if ("GET".equals(method)) {
doGet();//开发者模式验证
}else {
doPost();//接收消息
}
}
/*
* 响应post请求,微信中消息和菜单交互都是采用post请求
*/
private void doPost()throws IOException {
try {
//把微信返回的xml信息转义成map
Map<String, String> map = XmlUtil.xmlToMap(getRequest());
String fromUserName = map.get("FromUserName");//消息来源用户标识(一个OpenID)
String toUserName = map.get("ToUserName");//消息目的用户标识
String msgType = map.get("MsgType");//消息类型
String content = map.get("Content");//消息内容
if (msgType.equals(WechartConst.MsgType.EVENT)) { //事件类型
String event = map.get("Event");
if (event.equals(WechartConst.Event.SUBSCRIBE)) { //处理订阅事件
MessageService.subscribeForText(toUserName, fromUserName);
} else if (event.equals(WechartConst.Event.UNSUBSCRIBE)) { //处理取消订阅事件
MessageService.unsubscribe(toUserName, fromUserName);
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
renderNull();
}
}
/**
* 微信推送消息事件处理类
*/
public class MessageService {
/*
* 响应订阅事件
*/
public static void subscribeForText(String toUserName,String fromUserName){
System.out.println("用户:"+ fromUserName +"关注了公众号");
}
/*
* 响应取消订阅事件
*/
public static void unsubscribe(String toUserName,String fromUserName){
//可以进行取关后的其他后续业务处理
System.out.println("用户:"+ fromUserName +"取消关注~");
}
}
本文介绍如何通过微信公众号API处理用户的关注和取消关注事件,包括消息类型和事件类型的定义,XML数据包解析,以及事件推送处理流程。

2494

被折叠的 条评论
为什么被折叠?



