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

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

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。