标签:
先看下我们的基本用法:
@RequestMapping("/index") public ModelAndView index(HttpSession session){ System.out.println(session.getId()); ModelAndView modelAndView = new ModelAndView("main/index"); return modelAndView; }
如果我们添加断点进行调试,可以看到session类型是:
org.apache.catalina.session.StandardSessionFacade
依赖于tomcat容器。
Shiro是一款非常优秀的用户-角色-权限管理框架,具体可以Google下。当然,Shiro也提供Session管理模块,现在我们就使用shiro+spring实现一个与容器无关的session。
引入shiro的jar包
<properties> <shiroVersion>1.2.3</shiroVersion> </properties> <dependencies> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core</artifactId> <version>${shiroVersion}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-web</artifactId> <version>${shiroVersion}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>${shiroVersion}</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>${shiroVersion}</version> </dependency> </dependencies>
配置shiro(web.xml)
<filter> <filter-name>shiroFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>shiroFilter</filter-name> <url-pattern>*.html</url-pattern> </filter-mapping>
配置shiro(spring)
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="sessionManager" ref="sessionManager"/> </bean> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <property name="securityManager" ref="securityManager"/> </bean> <bean id="sessionManager" class="com.whereta.model.DemoSessionManager"> <property name="globalSessionTimeout" value="1000" /> <property name="deleteInvalidSessions" value="true" /> <property name="sessionValidationSchedulerEnabled" value="false" /> <property name="sessionDAO" ref="sessionDao" /> </bean> <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" /> <bean id="demoCache" class="com.whereta.model.DemoCache" /> <bean id="sessionDao" class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO"> <property name="sessionIdGenerator" ref="sessionIdGenerator" /> <property name="activeSessionsCache" ref="demoCache"/> </bean>
具体类用法
package com.whereta.model; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.session.Session; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * 该类是缓存工具类,提供session的存储和获取等方法 * @author Vincent * @time 2015/7/27 15:00 */ public class DemoCache implements Cache<Serializable, Session> { //模拟缓存存储session对象 private static final Map<Serializable, Session> map = new HashMap<Serializable, Session>(); public Session get(Serializable key) throws CacheException { //根据key获取缓存中的session return map.get(key); } public Session put(Serializable key, Session value) throws CacheException { //将session对象存入缓存 map.put(key, value); return value; } public Session remove(Serializable key) throws CacheException { //移除session中为key的对象 Session session = get(key); if (session != null) { session.setAttribute(key, null); return session; } return null; } public void clear() throws CacheException { //清除所有的session map.clear(); } public int size() { //返回session的数量 return map.size(); } public Set<Serializable> keys() { //返回所有session的key return map.keySet(); } public Collection<Session> values() { //返回所有session return map.values(); } }
package com.whereta.model; import org.apache.shiro.session.Session; import org.apache.shiro.session.mgt.eis.SessionIdGenerator; import java.io.Serializable; /** * sessionId生成工具类 * @author Vincent * @time 2015/7/27 11:45 */ public class DemoSessionIdGenerator implements SessionIdGenerator { public Serializable generateId(Session session) { //自定义规则生成sessionid return System.currentTimeMillis(); } }
package com.whereta.model; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.shiro.session.Session; import org.apache.shiro.session.mgt.SessionContext; import org.apache.shiro.web.servlet.ShiroHttpServletRequest; import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; import org.apache.shiro.web.util.WebUtils; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.io.Serializable; import java.util.HashMap; import java.util.Map; /** * 集成websession管理器,重写两个方法实现自己的需求 * @author Vincent * @time 2015/7/27 15:35 */ public class DemoSessionManager extends DefaultWebSessionManager { //自定义缓存,存储 客户端-sessionid public static final Map<String,Serializable> MAP=new HashMap<String, Serializable>(); private static Log log = LogFactory.getLog(DemoSessionManager.class); @Override protected Serializable getSessionId(ServletRequest request, ServletResponse response) { HttpServletRequest req= (HttpServletRequest) request; //假设以请求地址为key标注唯一一个客户端 String remoteHost = req.getRemoteHost(); //存入缓存 Serializable id = MAP.get(remoteHost); return id; } @Override protected void onStart(Session session, SessionContext context) { //判断是否是http请求 if (!WebUtils.isHttp(context)) { log.debug("SessionContext argument is not HTTP compatible or does not have an HTTP request/response " + "pair. No session ID cookie will be set."); return; } HttpServletRequest request = WebUtils.getHttpRequest(context); request.removeAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE); request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_IS_NEW, Boolean.TRUE); String remoteHost = request.getRemoteHost(); Serializable id = session.getId(); MAP.put(remoteHost,id); } }
通过以上配置,可以再次运行查看session,已经变为shiro的自定义session了
org.apache.shiro.web.servlet.ShiroHttpSession
标签:
原文地址:http://my.oschina.net/u/1792430/blog/484341