项目上线,闲来无事,把项目里用到的session共享贴出来,因为有多个项目要用到这个功能,所以这个部分功能独立出来了。总得来说,就是自己写了一个拦截器,在拦截器里面把session放进了redis里面,从而实现了session共享。
首先贴出web.xml的配置,和普通拦截器的配置一样:
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>com.dnkx.web.filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- session过期时间 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
然后是sessionFilter:
public class SessionFilter extends HttpServlet implements Filter {
/**
*
*/
private static final long serialVersionUID = -5723213015901607291L;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
request.setAttribute("hostname", InetAddress.getLocalHost().getHostName());
filterChain.doFilter(new HttpServletRequestWrapper(request, response),
servletResponse);
}
}
上面两段代码都是基础,没什么好解释的,下面贴出关键的HttpServletRequestWrapper类:
public class HttpServletRequestWrapper extends
javax.servlet.http.HttpServletRequestWrapper {
private static final String cookieId = "csid";
static String sessionHoldKey = "session_hold_key";
private String sessionId;
public HttpServletRequestWrapper(HttpServletRequest request, HttpServletResponse response) {
super(request);
sessionIdManage(request, response);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void sessionIdManage(HttpServletRequest request, HttpServletResponse response) {
Cookie[] cookies = request.getCookies();
if (cookies == null ) {
// logger.warn("request.getCookies() returns null,I didn't see it before");
} else {
for (int i = 0; i < cookies.length; i++) {
Cookie sCookie = cookies[i];
if (sCookie.getName().equals(cookieId)) {
sessionId = sCookie.getValue();
}
}
}
if (sessionId == null || sessionId.length() == 0) {
sessionIdCreate(response);
}
HashOperations hashOps = WebComponentFactory.getSessionRedisTemplate().opsForHash();
Long lastAccessedTime = (Long) hashOps.get(sessionId, sessionHoldKey);
long maxInactiveInterval = request.getSession().getMaxInactiveInterval() * 1000;
if (lastAccessedTime == null || maxInactiveInterval > 0 && System.currentTimeMillis() - lastAccessedTime > maxInactiveInterval) {
sessionIdCreate(response);
}
hashOps.put(sessionId, sessionHoldKey, System.currentTimeMillis());
WebComponentFactory.getSessionRedisTemplate().expire(sessionId,3, TimeUnit.DAYS);
}
private void sessionIdCreate(HttpServletResponse response) {
sessionId = java.util.UUID.randomUUID().toString();
Cookie mycookies = new Cookie(cookieId, sessionId);
mycookies.setPath("/");
response.addCookie(mycookies);
}
public HttpSession getSession(boolean create) {
return new HttpSessionSidWrapper(this.sessionId, super.getSession(create));
}
public HttpSession getSession() {
return new HttpSessionSidWrapper(this.sessionId, super.getSession());
}
}
上面这段代码是session共享的关键部分,这里需要了解cookie和session的机制,这里是用一个自己的cookie存了自己生成的sessionId返回给客户端,每次请求在根据cookie的值来做session的操作,sessionId是存在redis里面的,根据session做redis的get,set等操作,代码也很容易看懂。