本文章主要目的是配置session共享,爲了鞏固基礎,捎帶介紹了一些基礎知識(網上搜索後以爲最全面的特引過來,節省時間),基礎紮實的能夠自動忽略。java
基礎篇:web
1.瞭解java web中的session與cookie。spring
2.如何封裝request和session這兩個web項目中最經常使用的對象(以解決亂碼爲例)sql
進階篇:數據庫
3.利用memcache實現session共享cookie
在開發過程當中,爲了緩解訪問壓力,每每須要配置負載均衡,也就是相同的項目放在多臺機子上,保證一臺機子掛了,網站仍然能夠正常訪問,除了須要使用相同的數據源,資料源以外,最大的問題莫過於session的共享了。這裏session共享的核心在於改變原來session中的鍵值對存放在每臺機子各自的內存中的狀況,而是把session中的內容集中存放在一個nosql數據庫中。session
3.1封裝request對象:app
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對象dom
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