-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
WxSession
更详细的使用方法,请参考单元测试:me.chanjar.weixin.common.session.SessionTest
申明:下面所讲的关于微信Session的大部分代码都是copy自apache tomcat 7源代码的。
WxSession
是1.1.0
增加的新功能,有了Session的支持,操作方式和HttpSession
类似。
有了它,用户消息就有了状态,而不是之前那样每一个消息是无状态的,它们之间是互不联系的。
再举个例子,你可以开发一个猜大小的游戏,我们可以把随机生成的数值放到Session里,把用户每次消息过来的数字和Session 里的数字做比较,根据情况返回“大了”或“小了”的提示。之所以这么做是因为我们把正确答案放在了Session里,而Session把 每个消息都串联起来了。
在Wx*MessageInterceptor#intercept
方法里,系统会传入一个WxSessionManager
对象,
而在Wx*MessageHandler#handle
方法里,也会传入一个WxSessionManager
对象。如下面:
public boolean intercept(Wx*XmlMessage wxMessage,
Map<String, Object> context,
WxCpService wxCpService,
WxSessionManager sessionManager);
public Wx*XmlOutMessage handle(Wx*XmlMessage wxMessage,
Map<String, Object> context,
Wx*Service wx*Service,
WxSessionManager sessionManager);
WxSessionManager
就是用来获取WxSession
的工具。
WxSessionManager
有两个方法:
/**
* 获取某个sessionId对应的session,如果sessionId没有对应的session,则新建一个并返回。
*/
public WxSession getSession(String sessionId);
/**
* 获取某个sessionId对应的session,如果sessionId没有对应的session,若create为true则新建一个,否则返回null。
*/
public WxSession getSession(String sessionId, boolean create);
这里和HttpServletRequest.getSession
方法不同的是,需要你自己定义sessionId,在这里推荐使用wxMessage.getFromUserName
来
定义sessionId,这样一来的话就把这个用户的所有消息关联起来了。例子:
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage,
Map<String, Object> context,
WxCpService wxCpService,
WxSessionManager sessionManager) {
sessionManager.getSession(wxMessage.getFromUserName());
// ...
return null;
}
注意:如果不使用wxMessage.getFromUserName
作为sessionId,WxSessionManager
将无法自动清理过期session。
WxSession
和HttpSession
几乎完全一致,所以这里就不多说了:
public Object getAttribute(String name);
public Enumeration<String> getAttributeNames();
public void setAttribute(String name, Object value);
public void removeAttribute(String name);
public void invalidate();
本项目实现的WxSessionManager是基于内存的,开发人员可以根据自己的需要提供基于文件系统或者集群的实现。
只要在Wx*MessageRouter.route
前setSessionManager
为自己的实现就行了。
String encType = request.getParameter("encrypt_type");
String nonce = request.getParameter("nonce");
String timestamp = request.getParameter("timestamp");
String msgSignature = request.getParameter("msg_signature");
String signature = request.getParameter("signature");
String openid = request.getParameter("openid");
log.info("接收微信请求:[openid=[{}], [openid=[{}],[signature=[{}], encType=[{}], msgSignature=[{}],"
+ " timestamp=[{}], nonce=[{}], requestBody=[{}] ",
appid, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
// 请求里面没有对应信息。 // if (!this.wxMpService.switchover(appid)) { //appid // throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); // }
if (!wxMpService.checkSignature(timestamp, nonce, signature)) {
throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
}
return ResponseEntity.ok("");