您的位置:首页 > 数据库 > Redis

进击的java(8):springmvc+redis实现登录与拦截器

2015-06-29 20:37 721 查看
springmvc+redis实现登录与拦截器

1.web.xml

<filter>
    <filter-name>LoginCheckFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    <init-param>
        <param-name>targetFilterLifecycle</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>LoginCheckFilter</param-value>
    </init-param>
    <init-param>
        <param-name>excludePath</param-name>
        <param-value>/js/**;/css/**;/login/**;</param-value>
    </init-param> 
</filter>

> DelegatingFilterProxy是一个将web.xml和applicationConext.xml联系起来的东西,可以称作代理,xml和applicationConext里获得bean

> 之所以要这么写是因为LoginCheckFilter里面有一些依赖注入,不这么写就会报错:“NameNotFoundException: Name is not bound in this Context”

2.applicationConext.xml

<bean id="LoginCheckFilter" class="com.web.app.util.filter.LoginCheckFilter" />

3.LoginCheckFilter

public class LoginCheckFilter implements Filter {

    private Set<String> excludeSet;

    private String excludePath;

    @Autowired
    private JedisPoolService<String> jedisPoolService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    excludeSet = Sets.newHashSet();

    excludePath = filterConfig.getInitParameter("excludePath");
    if (Strings.isNullOrEmpty(excludePath)) {
        return;
    }

    Iterable<String> paths = Splitter.on(";").split(excludePath);
    for (String path : paths) {
        excludeSet.add(path);
    }

    /*
     * if (null == jedisPoolService) { jedisPoolService = new
     * JedisPoolServiceImpl<String>(); }
     */

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
        FilterChain chain) throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    HttpServletResponse httpResponse = (HttpServletResponse) response;

    // 判断是否在exclude中
    String path = LoginUtil.getRequestPath(httpRequest);
    if (LoginUtil.isInExcludePath(excludeSet, path)) {
        chain.doFilter(request, response);
        return;
    }

    String name = null;
    String session = null;

    Cookie[] cookies = httpRequest.getCookies();
    for (Cookie cookie : cookies) {
        if (cookie.getName().equals(LoginConstants.SESSION_USER)) {
            name = cookie.getValue();
            continue;
        }

        if (cookie.getName().equals(LoginConstants.REDIS_USER)) {
            session = cookie.getValue();
        }
    }

    if (Strings.isNullOrEmpty(name) || Strings.isNullOrEmpty(session)) {
        return;
    }

    String sessionName = jedisPoolService.get(session);
    if (name.equals(sessionName)) {
        jedisPoolService.setExpireSeconds(name,
                LoginConstants.SESSION_TIMEOUT);

        httpRequest.getSession().setAttribute(LoginConstants.SESSION_USER,
                name);
    } else {
        return;
    }

    chain.doFilter(request, response);

    }

> 重点是取出cookie来和jedisPool里的做比较

> jedisPoolService的实现:

@SuppressWarnings("unchecked")
    @Override
    public T get(String key) {
    // TODO Auto-generated method stub
    if (Strings.isNullOrEmpty(key)) {
        return null;
    }

    ShardedJedis jedis = shardedJedisPool.getResource();

    T obj = (T) SerializeUtil.unserialize(jedis.get(key.getBytes()));
    return obj;
}

LoginController

@RequestMapping(value = "/check", produces = { "application/json; charset=UTF-8" })
    @ResponseBody
    public ModelAndView login(@RequestParam("name") String name,
        @RequestParam("password") String password, ServletRequest request,
        ServletResponse response) {

    Preconditions.checkNotNull(name);
    Preconditions.checkNotNull(password);

    User user = new User();
    user.setName(name);
    user.setPassword(password);

    List<User> users = loginService.findUsers(user);
    if (CollectionUtils.isEmpty(users)) {
        return new ModelAndView("index");
    }

    HttpServletResponse httpResponse = (HttpServletResponse) response;
    HttpServletRequest httpRequest = (HttpServletRequest) request;
    Cookie cookie = new Cookie(LoginConstants.SESSION_USER, name);
    cookie.setMaxAge(60 * 60 * 24);
    cookie.setPath("/");
    httpResponse.addCookie(cookie);

    String session = LoginConstants.SESSION_PREFIX + UUIDtool.makeUUID();
    jedisPoolService.set(session, name);
    Cookie sessionCookie = new Cookie(LoginConstants.REDIS_USER, session);
    sessionCookie.setMaxAge(60 * 60 * 24);
    sessionCookie.setPath("/");
    httpResponse.addCookie(sessionCookie);

    httpRequest.getSession()
            .setAttribute(LoginConstants.SESSION_USER, name);

    return new ModelAndView("redirect:/index/show");
    // return new ModelAndView("index");
}

> cookie的整套逻辑是这样的:

cookie1: key:SESSION_SUER value:name

cookie2: key:REDIS_USER value:session

redis: key:session value:name

> 拦截器验证的逻辑是这样的:

cookie:从key拿到value(name ,session)

从redis里面用session拿到name

两个name做比较

注意cookie要设置path,因为cookie有有效范围,默认为本url及子目录

设置cookie.setPath("/");将cookie有效范围设置成根路径,就可以对所有url有效
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: