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+"/";
%>


Hello World!



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配置拦截器:


        
            
            
        
    
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实现自动登录效果的代码!



你可能感兴趣的:(SSM框架相关)