SpringMVC+Cookie+Session实现自动登录

实现自动登录其实并不是特别的困难,下面来介绍我所实现的自动登录的一种方式,首先,必须提到Cookie和Session,Cookie是保存在客户端的而Session是保存在服务端的,每次客户端通过游览器访问服务端的时候,会有一个JSESSIONID作为key值保存在Cookie中,服务端就这样区分每一个客户端的Session,在自动登录的时候,Cookie保存了用户名(自动保存JSESSIONID),然后在Session保存了有关于用户的一些登录信息,比如用户名、密码、登录时间啥的。自动登录的过程中涉及三个主要的方法(login、logout、autoLogin)以及两个jsp页面(index.jsp、login.jsp),下面直接给出代码!!

1.index.jsp

<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    response.sendRedirect(basePath+"logincookie");
%>
注:这是index.jsp页面的核心,让进index页面的用户自动发送一个请求到自动登录方法里边

2.login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<body>
<h2>Hello World!</h2>
<div style="align-content: center;">
    <form action="/login" method="post" >
        <input type="text" name="username" value="${user.username}"><br>
        <input type="text" name="password" value="${user.password}"><br>
        <input type="submit" value="点击">
    </form>
</div>
</body>
</html>
3.autoLogin Method
@RequestMapping("/logincookie")
    public String autoLogin(HttpServletRequest request,HttpServletResponse response){
        System.out.println("进入了自动登录的Controller!");
        Cookie[] cookies = request.getCookies();
        if(cookies==null){
            return "redirect:login";
        }
        HttpSession session = request.getSession(false);
        String sessionId = session.getId();

        for(Cookie cookie:cookies){
            if (cookie.getName().equals("JSESSIONID")) {
                if(!cookie.getValue().equals(sessionId)){
                    return "redirect:login";
                }
            }
        }

        for (Cookie cookie2:cookies){
            if(cookie2.getName().equals("username")&&cookie2.getValue()!=null){
                String cookieUsername = cookie2.getValue();
                try{
                    String realPassword = userService.getUserByUsername(cookieUsername).getPassword();
                    if (session.getAttribute("password").equals(realPassword)){
                        return "welcome";
                    }else{
                        return "redirect:login.jsp";
                    }

                }catch (NullPointerException e){
                    return "redirect:login.jsp";
                }

            }
        }

        return "redirect:login.jsp";
    }
注:这个意思也就是说,每次到index页面的时候首先是跳入到这个方法里边,通过这个方法判断cookie和session中保存的相关数据是否正确,如果正确的话就跳入到登录成功页面,不正确或者cookie、session失效的话就跳入login页面。

4.login Method

@RequestMapping("/login")
    public String login(HttpServletRequest request,String username, String password, HttpServletResponse response){
         if(username.equals("admin") && password.equals("admin")){

             HttpSession session = request.getSession();
             session.setAttribute("username",username);
             session.setAttribute("password",password);

            Cookie usernameCookie = new Cookie("username",username);
            usernameCookie.setMaxAge(500);
            usernameCookie.setPath("/");
            response.addCookie(usernameCookie);

            Cookie[] cookies = request.getCookies();
            System.out.println("外部的SessionId:"+session.getId());
            for (Cookie cookie:cookies){
                if(cookie.getName().equals("JSESSIONID")){
                    System.out.println("Cookie里边的:"+session.getId());
                    cookie.setValue(session.getId());
                    cookie.setPath("/");
                    cookie.setMaxAge(500);
                    response.addCookie(cookie);
                }
            }
         }
        return "welcome";
    }
5.logout Method

@RequestMapping("/logout")
    public String logout(HttpServletRequest request,HttpServletResponse response){
        //删除cookie
        Cookie usernameCookie = new Cookie("usernmae","");
        usernameCookie.setMaxAge(0);
        usernameCookie.setPath("/");
        response.addCookie(usernameCookie);
        request.getSession().removeAttribute("username");
        request.getSession().removeAttribute("password");
        return "redirect:login.jsp";
    }
其余剩下的service层和dao层的代码我就不给出了,很简单无非是一些查询!自动登录有很多种实现方法,除了用cookie还可以用一种url传递jsessionid的方式,这种情况是在游览器禁用cookie可以使用的,其实没有太大的区别,记住账号密码功能的实现也是类似的过程,无非是把保存在session或者cookie中的用户信息,还原到输入框当中,具体我这样写合不合规范我也不太清楚,至少功能原理上我算是摸了个八成熟!

----------------------------------------------------------------------------------------------------------------------------------分割线,上边的内容是通过请求重定向到一个Controller中来完成自动登录的验证,然而实际上我们最好用SpringMVC的拦截器来做自动登录的这个验证,这里Cookie存储的是username,Session保存了一个User(用户登录的对象),下边直接上代码:

1.在springmvc.xml配置拦截器:

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/welcomepage"/>
            <bean class="com.demo.AuthorizedInterceptor.AuthorizedInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
2.创建一个java拦截器类,实现HandlerInterceptor接口:

package com.demo.AuthorizedInterceptor;

import com.demo.pojo.User;
import com.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class AuthorizedInterceptor implements HandlerInterceptor {

    @Autowired
    private UserService userService;

    /**
     * preHandle方法是进行处理器拦截用的,顾名思义,该方法在Controller处理之前进行调用,SpringMVC中的Interceptor拦截器是链式的,可以同时存在,
     多个Interceptor,然后SpringMVC会根据声明的顺序一个接一个的执行,而且所有的Interceptor中的preHandler方法都会在Controller方法之前调用
     如果返回的是false的话就能够中断这个请求
     * @param request
     * @param response
     * @param o
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        System.out.println("进入了preHandle方法!!!!");
        //先从session拿取用户
        Cookie[] cookies = request.getCookies();
        if(cookies==null){
            response.sendRedirect("redirect:login");
        }
        HttpSession session = request.getSession(false);
        String sessionId = session.getId();

        for(Cookie cookie:cookies){
            if (cookie.getName().equals("JSESSIONID")) {
                if(!cookie.getValue().equals(sessionId)){
                    response.sendRedirect("redirect:login");
                }
            }
        }

        for (Cookie cookie2:cookies){
            if(cookie2.getName().equals("username")&&cookie2.getValue()!=null){
                String cookieUsername = cookie2.getValue();
                try{
                    String realPassword = userService.getUserByUsername(cookieUsername).getPassword();
                    User user = (User) session.getAttribute("user");
                    if (user.getPassword().equals(realPassword)){
                        response.sendRedirect("redirect:welcome");
                    }else{
                        response.sendRedirect("redirect:login");
                    }
                }catch (NullPointerException e){
                    response.sendRedirect("redirect:login");
                }

            }
        }
        return true;

    }

    /**
     *这个方法只会在当前的这个Interceptor的preHandler方法返回值为true的时候才执行。
     postHandler是进行处理器拦截用的。它的执行时间实在处理器进行处理之后,也就是在Controller
     的方法调用之后执行,但是他会在DispatcherServler进行视图渲染之前执行,也就是说在这个方法中,
     你可以对返回的ModelAndView进行操作。
     *这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用,
     这里与struts2里面的拦截器的执行过程有点像。
     *只是struts2里面的intercept方法中要手动调用的ActionInvocation的invoke方法,Struts2中调用
     ActionInvocation的invoke方法就是调用下一个Inteceptor或者是调用actio,然后在Interceptor之前
     调用的内容都写在invoke之前,要在Interceptor之后调用的都卸载invoke方法之后
     *
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param modelAndView
     * @throws Exception
     */
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("进入了postHandle方法!!!!");
    }

    /**
     *这个方法需要preHandler方法的返回值是true的时候才会执行。该方法将整个请求完成之后
     * 也就是DispatcherServlet渲染了视图才执行
     * 这个方法的主要用途是用于清理资源的,当然这个方法也只能在当前这个Interceptor的preHandler方法的返回值
     * 是true的时候才会执行
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e
     * @throws Exception
     */
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("进入了afterCompletion方法!!!!");
    }
}
剩下的代码就不给出了,与上边的雷同!包括记住密码和自动登录多少天都是类似的无非是加上时间什么的。下次会给出用Shiro实现自动登录效果的代码!



  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
1. 添加Redis依赖库 在项目的pom.xml文件中添加Redis的依赖库。 ```xml <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>2.3.2.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.0.0</version> </dependency> ``` 2. 配置Redis连接池 在SpringMVC的配置文件中添加Redis的连接池配置。 ```xml <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="localhost"/> <property name="port" value="6379"/> <<property name="password" value="password"/>> <property name="poolConfig"> <bean class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="1000"/> <property name="maxIdle" value="100"/> <property name="minIdle" value="10"/> <property name="maxWaitMillis" value="10000"/> </bean> </property> </bean> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory"/> </bean> ``` 3. 配置Session共享 在SpringMVC的配置文件中添加Session共享的配置。 ```xml <bean id="redisHttpSessionConfiguration" class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration"> <property name="maxInactiveIntervalInSeconds" value="1800"/> </bean> <bean class="org.springframework.session.web.http.CookieHttpSessionIdResolver"> <constructor-arg name="cookieName" value="SESSION_ID"/> <property name="cookiePath" value="/"/> <property name="cookieMaxAge" value="-1"/> </bean> ``` 4. 启用Session共享 在SpringMVC的配置文件中启用Session共享。 ```xml <bean class="org.springframework.session.web.http.SessionRepositoryFilter"> <constructor-arg> <bean class="org.springframework.session.data.redis.RedisOperationsSessionRepository"> <constructor-arg ref="redisTemplate"/> </bean> </constructor-arg> </bean> <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="sessionAttributeStore"> <bean class="org.springframework.session.web.http.SessionRepositoryFilter"> <constructor-arg> <bean class="org.springframework.session.data.redis.RedisOperationsSessionRepository"> <constructor-arg ref="redisTemplate"/> </bean> </constructor-arg> </bean> </property> </bean> ``` 5. 测试 启动项目后,访问任意一个页面,然后在Redis中就可以看到Session的信息了。 ```shell redis-cli 127.0.0.1:6379> keys * 1) "spring:session:sessions:5b5d4b4f-9a9f-4e4e-bd56-4b4c7f1d8f0b" 127.0.0.1:6379> get spring:session:sessions:5b5d4b4f-9a9f-4e4e-bd56-4b4c7f1d8f0b "\xac\xed\x00\x05sr\x00\x17java.util.HashMap\x85\x95\x1d\x9b\x94\xee\x0c\x00\x00\x03I\x00\x05valuexr\x00\x10java.lang.String\x86\xac\xed\x00\x05sr\x00\x11java.lang.String\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01Ljava/lang/String;L\x00\x04namet\x00\x12Ljava/lang/String;L\x00\x08usernameq\x00~\x00\x01sq\x00~\x00\x0bpasswordq\x00~\x00\x0b" ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值