webwork结合memcached实现sna架构
实现思路,使用一个拦截器实现session的处理:
使用方法:
1、配置拦截器
<interceptor name="snaInterceptor"></interceptor>
<interceptor-ref name="snaInterceptor"></interceptor-ref>
2、配置spring
<bean id="cacheManager" destroy-method="close"></bean>
??<constructor-arg value="127.0.0.1:11212"></constructor-arg>
?
如果使用struct2,则需要修改相应的接口,并增加setCacheManager方法
/** * $Revision: 1.0 $ * Created: 2007-6-1 * $Date: 2007-6-1 $ * * Author: Keven Chen */package com.comwave.sna.filter;import java.io.IOException;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.Enumeration;import java.util.Iterator;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.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import com.comwave.sna.SessionMap;import com.comwave.sna.cache.provider.MemcachedCacheManager;/** * @author Keven Chen * @version $Revision 1.0 $ * */public class SNAFilter implements Filter {private static final String REMOVE_ATTRIBUTE_METHOD = "removeAttribute";private static final String SET_ATTRIBUTE_METHOD = "setAttribute";private static final String GET_SESSION_METHOD = "getSession";private static final String SERVER_LIST = "serverList";private static final String SESSION_NAME = "cookie-session-id";private MemcachedCacheManager cacheManager;public void init(FilterConfig config) throws ServletException {String serverList = config.getInitParameter(SERVER_LIST);if(serverList == null || serverList.trim().length() ==0){throw new ServletException("SNAFilter missing serverList parameter.");}cacheManager = new MemcachedCacheManager(serverList);}public void destroy() {if (cacheManager != null) {cacheManager.close();}}public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {final HttpServletRequest hrequest = (HttpServletRequest) request;final HttpServletResponse hresponse = (HttpServletResponse) response;String sessionId = getSessionId(hrequest,hresponse);SessionMap session = getSession(sessionId);initialHttpSession(session,hrequest.getSession());try {chain.doFilter(proxyRequest(hrequest,session), hresponse);} finally {if(session.isClear() || session.isEmpty()){boolean result = cacheManager.flushCache(sessionId);}else if(session.isModified()){session.setModified(false);boolean result = cacheManager.putToCache(sessionId, session);}}}private HttpServletRequest proxyRequest(final HttpServletRequest request,final SessionMap session){final HttpSession hSession = request.getSession();return (HttpServletRequest) Proxy.newProxyInstance(HttpServletRequest.class.getClassLoader(),new Class[] { HttpServletRequest.class }, new InvocationHandler() {private HttpSession proxySession = null;public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {if(method.getName().equalsIgnoreCase(GET_SESSION_METHOD)){if(proxySession == null){proxySession = proxySession(hSession,session);}return proxySession;}return method.invoke(request, args);}});}private HttpSession proxySession(final HttpSession hsession,final SessionMap session){return (HttpSession) Proxy.newProxyInstance(HttpSession.class.getClassLoader(), new Class[] {HttpSession.class}, new InvocationHandler() {public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String methodName = method.getName();if(methodName.equalsIgnoreCase(SET_ATTRIBUTE_METHOD)){System.out.println("name:"+args[0]+",value:"+args[1]);session.put(args[0], args[1]);}else if(methodName.equalsIgnoreCase(REMOVE_ATTRIBUTE_METHOD)){System.out.println("remove:"+args[0]);session.remove(args[0]);}return method.invoke(hsession, args);}});}private void initialHttpSession(SessionMap session, HttpSession hsession){Enumeration oldAttributes = hsession.getAttributeNames();while(oldAttributes.hasMoreElements()){hsession.removeAttribute((String)oldAttributes.nextElement());}Iterator newAttributes = session.keySet().iterator();while(newAttributes.hasNext()){String attribute = (String) newAttributes.next();hsession.setAttribute(attribute, session.get(attribute));}}private String getSessionId(HttpServletRequest request,HttpServletResponse hresponse){Cookie[] cookies = request.getCookies();String sessionId = null ;if (cookies != null) {for (int i = 0; cookies != null && i < cookies.length; i++) {if (SESSION_NAME.equals(cookies[i].getName())) {sessionId = cookies[i].getValue();break;}}}if(sessionId == null || sessionId.trim().length() == 0){sessionId = buildSessionId(request);createCookie(sessionId,hresponse);}return sessionId;}private void createCookie(String sessionId,HttpServletResponse response) {Cookie cookie = new Cookie(SESSION_NAME,sessionId);cookie.setPath("/");response.addCookie(cookie);}private String buildSessionId(HttpServletRequest request) {return request.getSession().getId();}protected SessionMap getSession(String Id){Object value = cacheManager.getFromCache(Id);if(value == null){return new SessionMap();}return (SessionMap) value;}}