我们架构的改变会牵涉代码的改变,架构是一步一步演进的,代码也要一步一步演进,相信这个过程能够学到很多很多,
如果重置redis的一个时间,我们先来到代码里边,首先我们这个实现方案是通过过滤器来实现,过滤所有.do请求结尾的,
然后在里面进行一个判断,并把session进行一个重置时间,首先在Controller里面,加一个common包,这个common包不同于
上面的common包,上面的是业务上实现的各种common,而这个common加到controller里,它会对Controller造成影响,我们在这里
加一个类,SessionExpireFilter,这么一个类,他来实现Filter这个接口,这个Filter不要导错包,导入javax.servlet里面的
filter,然后实现他的方法,因为它是一个接口,初始化和destroy我们就不写了,我们继续写,主要是写doFilter,首先要做的是,
把ServletRequest强转成HttpServletRequest,因为HttpServletRequest继承ServletRequest,然后我们拿到loginToken,
这里面要做一个判断,用Apache的一个包,如果拿到的一个cookie,也就是mmall_login_token不是空,那我们就用redis
里面拿user,这个用户的JSON字符串,然后对他进行反序列化,那这里要判断一下,如果user不等于空,这里面的逻辑就是说,
先判断loginToken,是否为空,或者空字符串
/**
* <p>Checks if a String is not empty ("") and not null.</p>
*
* <pre>
* StringUtils.isNotEmpty(null) = false
* StringUtils.isNotEmpty("") = false
* StringUtils.isNotEmpty(" ") = true
* StringUtils.isNotEmpty("bob") = true
* StringUtils.isNotEmpty(" bob ") = true
* </pre>
*
* @param str the String to check, may be null
* @return <code>true</code> if the String is not empty and not null
*/
public static boolean isNotEmpty(String str) {
return !StringUtils.isEmpty(str);
}
/**
* <p>Checks if a String is empty ("") or null.</p>
*
* <pre>
* StringUtils.isEmpty(null) = true
* StringUtils.isEmpty("") = true
* StringUtils.isEmpty(" ") = false
* StringUtils.isEmpty("bob") = false
* StringUtils.isEmpty(" bob ") = false
* </pre>
*
* <p>NOTE: This method changed in Lang version 2.0.
* It no longer trims the String.
* That functionality is available in isBlank().</p>
*
* @param str the String to check, may be null
* @return <code>true</code> if the String is empty or null
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
如果不为空,符合条件,继续拿user信息,这里面还判断一下,如果user不为空,则重置session的时间,既调用
expire命令,那我们这个filter就写完了,这里面的逻辑是非常简单的,我们还要在web.xml中把filter配置上
package com.mmall.controller.common;
import com.mmall.common.Const;
import com.mmall.pojo.User;
import com.mmall.util.CookieUtil;
import com.mmall.util.JsonUtil;
import com.mmall.util.RedisShardedPoolUtil;
import org.apache.commons.lang.StringUtils;
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.HttpServletRequest;
import java.io.IOException;
/**
*
* @author Leon.Sun
*
*/
public class SessionExpireFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
String loginToken = CookieUtil.readLoginToken(httpServletRequest);
if(StringUtils.isNotEmpty(loginToken)){
//判断logintoken是否为空或者"";
//如果不为空的话,符合条件,继续拿user信息
String userJsonStr = RedisShardedPoolUtil.get(loginToken);
User user = JsonUtil.string2Obj(userJsonStr,User.class);
if(user != null){
//如果user不为空,则重置session的时间,即调用expire命令
RedisShardedPoolUtil.expire(loginToken, Const.RedisCacheExtime.REDIS_SESSION_EXTIME);
}
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
public interface RedisCacheExtime{
int REDIS_SESSION_EXTIME = 60 * 30;//30分钟
}
重置session时间的filter,首先加一个filter节点
<filter>
<filter-name>sessionExpireFilter</filter-name>
<filter-class>com.learn.controller.common.SessionExpireFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionExpireFilter</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>
全是以do结尾的都走这个拦截器,来重置它的session时间,那这个sessionFilter就加完了
我们TOMCAT集群在横线扩展的时候,想达到这种效果,就会衍生出来各种的一系列问题,例如我们一开始把SESSION,
通过cookie,都写到redis里面,同时也能读到,但是我们还要考虑,session有效期的问题,所以我们又加了一个expireFilter,
因为TOMCAT集群非常非常重要,能够提高大家的思维能力,架构能力,还有编码能力,最重要的实战经验