1.Web應(yīng)用Session什么時候生成
需要明確一點金顿,訪問靜態(tài)html文件的時候是不會生成Session的焦人,Session的生成必須調(diào)用request.getSession()或者request.getSession(true)坯苹,request.getSession(false)不會生成Session篓冲。
JSP文件中默認(rèn)自動添加<%@ page session="true"表蝙,表示生成Session,jsp文件其實最后也是生成了Servlet類寒锚,添加了前面的配置后也會在Servlet類中調(diào)用request.getSession(true)劫映。
如果單獨的jsp頁面不想生成Session可以在文件開頭加入<%@ page session="false"%>。但是有些時候我們整個項目都不需要tomcat管理Session刹前,如果每一個JSP泳赋、Servlet都手動添加<%@ page session="false"%>是不是有點太麻煩了?
2.如何不生成Session
先來借鑒下Shiro是如何自己管理Session 的喇喉,Shiro框架在管理權(quán)限時祖今,用戶的Session是通過框架來管理的。
需要認(rèn)證的資源被訪問時Shiro會判斷Session。在集成了Shiro框架的web項目中千诬,對getSession()方法debug下去發(fā)現(xiàn)耍目,原來Shiro重寫了getSession()來實現(xiàn)Session的管理。下面是Shiro的Session管理源碼
public class ShiroHttpServletRequest extends HttpServletRequestWrapper {
...
public HttpSession getSession(boolean create) {
HttpSession httpSession;
if (isHttpSessions()) { //默認(rèn)tomcat的session
httpSession = super.getSession(false);
if (httpSession == null && create) {
//Shiro 1.2: assert that creation is enabled (SHIRO-266):
if (WebUtils._isSessionCreationEnabled(this)) {
httpSession = super.getSession(create);
} else {
throw newNoSessionCreationException();
}
}
} else {//Shiro管理的Session
if (this.session == null) {
boolean existing = getSubject().getSession(false) != null;
Session shiroSession = getSubject().getSession(create);
if (shiroSession != null) {
this.session = new ShiroHttpSession(shiroSession, this, this.servletContext);
if (!existing) {
setAttribute(REFERENCED_SESSION_IS_NEW, Boolean.TRUE);
}
}
}
httpSession = this.session;
}
return httpSession;
}
public HttpSession getSession() {
return getSession(true);
}
...
}
從上面Shiro源碼可以看到原來Shiro重寫了默認(rèn)的HttpServletRequestWrapper類徐绑。
3.重寫HttpServletRequestWrapper.getSession()邪驮,實現(xiàn)自定義session
我們也可以模仿Shiro的思路,自定義管理應(yīng)用的Session傲茄,這一步的意義非常重大毅访,可以解鎖很多姿勢,驚喜放在文末盘榨。
//1.繼承HttpServletRequestWrapper 重寫getSession()方法
public class MyHttpServletRequest extends HttpServletRequestWrapper{
...
}
//2.配置一個過濾器喻粹,在過濾器中配置自己的Request類
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new MyHttpServletRequest((HttpServletRequest) request), response);
}
上面的管理方法對于Session 的管理變的非常靈活,完全可以按照項目的需求繼續(xù)拓展草巡,比如Session的分布式管理守呜,把Session數(shù)據(jù)緩存管理;移動端APP的Session管理等山憨。
4.擴展
因為這里自定義session是通過filter接入的弛饭。我們完全可以根據(jù)需求定義多個filter,實現(xiàn)一個應(yīng)用的多種session管理方案萍歉。比如一個web應(yīng)用有web侣颂、App和微信三種前端渠道;那么web我們可以用redis管理session枪孩、app和微信可以用jwt(json web token)憔晒。