关于管理Session的探讨

1.Web应用Session什么时候生成

需要明确一点,访问静态html文件的时候是不会生成Session的,Session的生成必须调用request.getSession()或者request.getSession(true),request.getSession(false)不会生成Session。

JSP文件中默认自动添加<%@ page session="true",表示生成Session,jsp文件其实最后也是生成了Servlet类,添加了前面的配置后也会在Servlet类中调用request.getSession(true)。

如果单独的jsp页面不想生成Session可以在文件开头加入<%@ page session="false"%>。但是有些时候我们整个项目都不需要tomcat管理Session,如果每一个JSP、Servlet都手动添加<%@ page session="false"%>是不是有点太麻烦了?

2.如何不生成Session

先来借鉴下Shiro是如何自己管理Session 的,Shiro框架在管理权限时,用户的Session是通过框架来管理的。

关于管理Session的探讨_第1张图片
shiro配置

需要认证的资源被访问时Shiro会判断Session。在集成了Shiro框架的web项目中,对getSession()方法debug下去发现,原来Shiro重写了getSession()来实现Session的管理。下面是Shiro的Session管理源码

public  class ShiroHttpServletRequest extends HttpServletRequestWrapper {  
...
public HttpSession getSession(boolean create) {  
  
        HttpSession httpSession;  
  
        if (isHttpSessions()) { //默认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重写了默认的HttpServletRequestWrapper类。

3.重写HttpServletRequestWrapper.getSession(),实现自定义session

我们也可以模仿Shiro的思路,自定义管理应用的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 的管理变的非常灵活,完全可以按照项目的需求继续拓展,比如Session的分布式管理,把Session数据缓存管理;移动端APP的Session管理等。

4.扩展

因为这里自定义session是通过filter接入的。我们完全可以根据需求定义多个filter,实现一个应用的多种session管理方案。比如一个web应用有web、App和微信三种前端渠道;那么web我们可以用redis管理session、app和微信可以用jwt(json web token)。

你可能感兴趣的:(关于管理Session的探讨)