本文章主要目的是配置session共享,为了巩固基础,捎带介绍了一些基础知识(网上搜索后觉得最全面的特引过来,节省时间),基础扎实的可以自动忽略。
基础篇:
2.如何封装request和session这两个web项目中最常用的对象(以解决乱码为例)
进阶篇:
3.利用memcache实现session共享
在开发过程中,为了缓解访问压力,往往需要配置负载均衡,也就是相同的项目放在多台机子上,保证一台机子挂了,网站仍然可以正常访问,除了需要使用相同的数据源,资料源之外,最大的问题莫过于session的共享了。这里session共享的核心在于改变原来session中的键值对存放在每台机子各自的内存中的情况,而是把session中的内容集中存放在一个nosql数据库中。
3.1封装request对象:
package com.sse.roadshow.session; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import com.sse.roadshow.common.SpyMemcachedManager; public class HttpServletRequestWrapper extends javax.servlet.http.HttpServletRequestWrapper { String sid = ""; private SpyMemcachedManager spyMemcachedManager; public HttpServletRequestWrapper(String sid, HttpServletRequest request,SpyMemcachedManager spyMemcachedManager) { super(request); this.sid = sid; this.spyMemcachedManager = spyMemcachedManager; } public HttpSession getSession(boolean create) { return new HttpSessionSidWrapper(this.sid, super.getSession(create), this.spyMemcachedManager); } public HttpSession getSession() { return new HttpSessionSidWrapper(this.sid, super.getSession(), this.spyMemcachedManager); } }
通过封装传递数据源,并且覆盖getSession方法,自定义的session对象在下一步
3.2封装session对象
package com.sse.roadshow.session; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpSession; import com.sse.roadshow.common.Constants; import com.sse.roadshow.common.SpyMemcachedManager; import com.sse.roadshow.vo.Enumerator; public class HttpSessionSidWrapper extends HttpSessionWrapper { private String sid = ""; private Map map = new HashMap(); private SpyMemcachedManager spyMemcachedManager; @SuppressWarnings("rawtypes") public HttpSessionSidWrapper(String sid, HttpSession session, SpyMemcachedManager spyMemcachedManager) { super(session); if (spyMemcachedManager == null) { System.out.println("spyMemcachedManager is null....."); return; } this.spyMemcachedManager = spyMemcachedManager; this.sid = sid; Map memSession = null; memSession = (Map) this.spyMemcachedManager.get(sid); //sid没有加入到session中,需要初始化session,替换为自定义session if (memSession == null) { // System.out.println("memSession is null"); memSession = new HashMap(); // this.spyMemcachedManager.set(sid, memSession, Constants.SPMEM_EXPTIME); if (session != null) { Enumeration<String> names = session.getAttributeNames(); while (names.hasMoreElements()) { String key = (String) names.nextElement(); memSession.put(key, session.getAttribute(key)); } } } this.map = memSession; } public Object getAttribute(String key) { if (this.map != null && this.map.containsKey(key)) { return this.map.get(key); } else { return null; } } @SuppressWarnings({ "unchecked", "rawtypes" }) public Enumeration getAttributeNames() { return (new Enumerator(this.map.keySet(), true)); // return super.getAttributeNames(); } public void invalidate() { // super.invalidate(); this.map.clear(); long s1= System.currentTimeMillis(); try { spyMemcachedManager.delete(sid); System.out.print("removeSession sid is:" + sid); } finally{ System.out.println(System.currentTimeMillis() -s1); } } public void removeAttribute(String name) { // super.removeAttribute(name); this.map.remove(name); attributeChange(); // System.out.print("removeAttribute"); // System.out.println("key : " + name); } @SuppressWarnings("unchecked") public void setAttribute(String name, Object value) { // super.setAttribute(name, value); this.map.put(name, value); attributeChange(); // System.out.print("setAttribute-"); // System.out.println("key : " + name + ", value : " + value); } private void attributeChange() { spyMemcachedManager.set(sid, this.map, Constants.MYFILTER_COOKIE_EXPTIME); } }
3.3引入我们刚才封装好的request对象:
使用过滤器过滤对应路径的请求,引入自定义request:
3.3.1自定义过滤器:
package com.sse.roadshow.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.context.support.WebApplicationContextUtils; import com.sse.roadshow.common.Constants; import com.sse.roadshow.common.SpyMemcachedManager; import com.sse.roadshow.common.Util; import com.sse.roadshow.session.HttpServletRequestWrapper; public class MemcachedSessionFilter extends HttpServlet implements Filter { private static final long serialVersionUID = 8928219999641126613L; // private FilterConfig filterConfig; private String cookieDomain = ""; private String cookiePath = "/"; private SpyMemcachedManager spyMemcachedManager; public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String sessionId = "XmlBeanDefinitionReaderSid"; HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; Cookie cookies[] = request.getCookies(); Cookie sCookie = null; String sid = ""; if (cookies != null && cookies.length > 0) { for (int i = 0; i < cookies.length; i++) { sCookie = cookies[i]; if (sCookie.getName().equals(sessionId)) { sid = sCookie.getValue(); } } } if (sid == null || sid.length() == 0) { sid = java.util.UUID.randomUUID().toString(); Cookie mycookies = new Cookie(sessionId, sid); mycookies.setMaxAge(-1); mycookies.setPath("/"); mycookies.setHttpOnly(true); mycookies.setDomain(Constants.DOMAIN); response.addCookie(mycookies); } spyMemcachedManager = getBean(request); filterChain.doFilter(new HttpServletRequestWrapper(sid, request, spyMemcachedManager), servletResponse); } private SpyMemcachedManager getBean(HttpServletRequest request) { if(Util.isNull(spyMemcachedManager)) { spyMemcachedManager = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext()).getBean(SpyMemcachedManager.class); } return spyMemcachedManager; } public void init(FilterConfig filterConfig) throws ServletException { // this.filterConfig = filterConfig; // this.sessionId = filterConfig.getInitParameter("sessionId"); this.cookiePath = filterConfig.getInitParameter("cookiePath"); if (this.cookiePath == null || this.cookiePath.length() == 0) { this.cookiePath = "/"; } this.cookieDomain = filterConfig.getInitParameter("cookieDomain"); if (this.cookieDomain == null) { this.cookieDomain = Constants.DOMAIN; } } public SpyMemcachedManager getSpyMemcachedManager() { return spyMemcachedManager; } public void setSpyMemcachedManager(SpyMemcachedManager spyMemcachedManager) { this.spyMemcachedManager = spyMemcachedManager; } }
3.3.2.在web.xml中配置filter:
<!-- session共享过滤器 --> <filter> <filter-name>mySessionFilter</filter-name> <filter-class>com.sse.roadshow.filter.MemcachedSessionFilter</filter-class> </filter> <filter-mapping> <filter-name>mySessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
这样session共享就配置完毕了。
http://blog.csdn.net/shandalue/article/details/41522043