java項目使用memcache實現session共享+session基礎

本文章主要目的是配置session共享,爲了鞏固基礎,捎帶介紹了一些基礎知識(網上搜索後覺得最全面的特引過來,節省時間),基礎紮實的可以自動忽略。


基礎篇:

1.瞭解java web中的session與cookie。

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);

}

}


這裏覆蓋session的操作方法,取值使用我們從memcache中查出來的數據


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共享就配置完畢了。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章