session保存到redis简单实现

在负载均衡情况下,如果用户访问不同的机器,如果没有做session同步,用户就会被提出,这样用户体验非常不好,所以我们很远必要做session同步,把session放到reids缓存服务器就能很好的解决问题。下面是代码简单的实现。

一、配置web.xml过滤器:

<filter>
		<filter-name>sessionFilter</filter-name>
		<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>sessionFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

二、配置对应的过滤器名字:

<bean id="sessionFilter" class="com.plateno.interceptor.SessionFilter">
		<property name="redisTemplate" ref="redisTemplate"/>
	</bean>

三、 SessionFilter的实现:

public class SessionFilter extends GenericFilterBean {

	private RedisTemplate redisTemplate;
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("filter");
		HttpServletRequest re = (HttpServletRequest)request;
		HttpServletResponse res = (HttpServletResponse)response;
		TerryHttpServletRequestWrapper wrapper = new TerryHttpServletRequestWrapper(re,res,redisTemplate);
		chain.doFilter(wrapper, response);
	}
	public RedisTemplate getRedisTemplate() {
		return redisTemplate;
	}
	public void setRedisTemplate(RedisTemplate redisTemplate) {
		this.redisTemplate = redisTemplate;
	}
}

四、 TerryHttpServletRequestWrapper的实现:

public class TerryHttpServletRequestWrapper extends HttpServletRequestWrapper {

	private CacheHttpSession session;
	private HttpServletResponse response;
	private RedisTemplate redisTemplate;
	public TerryHttpServletRequestWrapper(HttpServletRequest request, HttpServletResponse response,RedisTemplate redisTemplate) {
		super(request);
		this.response = response;
		this.redisTemplate = redisTemplate;
	}

	@Override
	public HttpSession getSession(boolean create) {
		if(session != null) {
			return session;
		}
		String sid = "terry" + System.currentTimeMillis();
		writeSidToCookie(sid);
		session = new CacheHttpSession(null,sid,redisTemplate);
		return session;
	}

	@Override
	public HttpSession getSession() {
		return getSession(false);
	}
	protected void writeSidToCookie(String sid) {
		Cookie mycookies = new Cookie("terry", sid);
		mycookies.setMaxAge(-1);
		mycookies.setDomain("locahost");
		mycookies.setPath("/");
		response.addCookie(mycookies);
	}
}
五、CacheHttpSession的实现:

public class CacheHttpSession extends HttpSessionWrapper {

	private String sid;
	private RedisTemplate redisTemplate;
	private StringRedisSerializer stringSerializer = new StringRedisSerializer();
	public CacheHttpSession(HttpSession session,String sid,RedisTemplate redisTemplate) {
		super(session);
		this.sid = sid;
		this.redisTemplate = redisTemplate;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Enumeration<String> getAttributeNames() {
		final byte[] key = stringSerializer.serialize(sid);
		Object result = redisTemplate.execute(new RedisCallback<Object>() {
			@Override
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				Set<byte[]> set = connection.keys(key);
				return set;
			}
		});
		if(result != null) {
			Set<byte[]> s = (Set<byte[]>)result;
			Set<String> ss = new HashSet<String>();
			for(byte[] b : s) {
				ss.add(stringSerializer.deserialize(b));
			}
			Enumeration<String> en = new Vector(ss).elements();
			return en;
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void setAttribute(String name, Object value) {
		final byte[] key = stringSerializer.serialize(name);
		final byte[] v = stringSerializer.serialize((String)value);
		redisTemplate.execute(new RedisCallback<Object>() {
			@Override
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				connection.set(key, v);
				return null;
			}
		});
	}

	@Override
	public Object getAttribute(String name) {
		final byte[] key = stringSerializer.serialize(name);
		@SuppressWarnings("unchecked")
		Object value = redisTemplate.execute(new RedisCallback<Object>() {
			@Override
			public Object doInRedis(RedisConnection connection)
					throws DataAccessException {
				return connection.get(key);
			}
		});
		return value;
	}

	@Override
	public String getId() {
		return sid;
	}
}

六、HttpSessionWrapper的实现:

public class HttpSessionWrapper implements HttpSession {

	private HttpSession session;
	public HttpSessionWrapper(HttpSession session) {
		this.session = session;
	}
	@Override
	public long getCreationTime() {
		return this.session.getCreationTime();
	}

	@Override
	public String getId() {
		return this.session.getId();
	}

	@Override
	public long getLastAccessedTime() {
		return this.session.getLastAccessedTime();
	}

	@Override
	public ServletContext getServletContext() {
		return this.session.getServletContext();
	}

	@Override
	public void setMaxInactiveInterval(int interval) {
		this.session.setMaxInactiveInterval(interval);
	}

	@Override
	public int getMaxInactiveInterval() {
		return this.session.getMaxInactiveInterval();
	}

	@Override
	public HttpSessionContext getSessionContext() {
		return this.session.getSessionContext();
	}

	@Override
	public Object getAttribute(String name) {
		return this.session.getAttribute(name);
	}

	@Override
	public Object getValue(String name) {
		return this.session.getValue(name);
	}

	@Override
	public Enumeration<String> getAttributeNames() {
		return this.session.getAttributeNames();
	}

	@Override
	public String[] getValueNames() {
		return this.session.getValueNames();
	}

	@Override
	public void setAttribute(String name, Object value) {
		this.session.setAttribute(name,value);
	}

	@Override
	public void putValue(String name, Object value) {
		this.session.putValue(name,value);
	}

	@Override
	public void removeAttribute(String name) {
		this.session.removeAttribute(name);
	}

	@Override
	public void removeValue(String name) {
		this.session.removeValue(name);
	}

	@Override
	public void invalidate() {
		this.session.invalidate();
	}

	@Override
	public boolean isNew() {
		return this.session.isNew();
	}
}

以上代码就能把session保存到redis,当然这其中还有很多问题,比如sessionId的生成,session过去,对象序列化(测试为了方便统一用了string),等等很多问题。以后有时间再完善。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值