Skip to content
Binary Wang edited this page Feb 13, 2019 · 2 revisions

更详细的使用方法,请参考单元测试:me.chanjar.weixin.common.session.SessionTest

申明:下面所讲的关于微信Session的大部分代码都是copy自apache tomcat 7源代码的。

WxSession1.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

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

WxSessionHttpSession几乎完全一致,所以这里就不多说了:

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

本项目实现的WxSessionManager是基于内存的,开发人员可以根据自己的需要提供基于文件系统或者集群的实现。 只要在Wx*MessageRouter.routesetSessionManager为自己的实现就行了。

Clone this wiki locally