zoukankan      html  css  js  c++  java
  • SpringMVC-拦截器做一个登录认证的小Demo

    拦截器

    拦截器的定义

    处理器拦截器类似于servlet开发中的filter,用于对处理器进行预处理和后处理。

    定义拦截器,实现HandlerInterceptor这个接口

    接口的实现需要导入包import org.springframework.web.servlet.HandlerInterceptor;

    这个包不能导错,不然不能自动添加方法。

    代码:

    package com.jch.interceptor;
    
     
    
    import javax.servlet.http.HttpServletRequest;
    
    import javax.servlet.http.HttpServletResponse;
    
     
    
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import org.springframework.web.servlet.ModelAndView;
    
     
    
     
    
    public class HandlerInterceptor1 implements HandlerInterceptor{
    
     
    
             /**
    
              *  进入handler方法之前执行
    
              *  用于身份认证,身份校验
    
              *  比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不在向下执行
    
              */
    
             @Override
    
             public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
    
                       // TODO Auto-generated method stub
    
                       return false;
    
             }
    
            
    
             /**
    
              *  进入handler之后,返回modelandview之前执行
    
              *  应用场景从modelandview出发,将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图
    
              */
    
             @Override
    
             public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    
                                throws Exception {
    
                       // TODO Auto-generated method stub
    
                      
    
             }
    
     
    
             /**
    
              *  执行handler完成执行此方法
    
              *  应用场景:统一异常处理,统一日志处理
    
              */
    
             @Override
    
             public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    
                                throws Exception {
    
                       // TODO Auto-generated method stub
    
                      
    
             }
    
            
    
     
    
    }
    View Code

    拦截器的配置

    SpringMVC拦截器针对HandlerMapping进行拦截设置

    SpringMVC拦截器针对HandlerMapping进行拦截器设置

    如果在某个HandlerMapping中配置拦截,经过该HandlerMapping映射成功的handler最终使用该拦截器。

    一般不推荐使用,配置过于麻烦

    类似全局的拦截器

    SpringMVC配置类似全局的拦截器,SpringMVC框架将配置的类似全局的拦截器注入到每一个HandlerMapping中

    拦截器的测试

    测试需求

    测试多个拦截器各个方法的执行时机

    编写两个拦截器

    代码;

    package com.jch.interceptor;
    
     
    
    import javax.servlet.http.HttpServletRequest;
    
    import javax.servlet.http.HttpServletResponse;
    
     
    
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import org.springframework.web.servlet.ModelAndView;
    
     
    
     
    
    public class HandlerInterceptor1 implements HandlerInterceptor{
    
     
    
             /**
    
              *  进入handler方法之前执行
    
              *  用于身份认证,身份校验
    
              *  比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不在向下执行
    
              */
    
             @Override
    
             public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
                       // TODO Auto-generated method stub
    
                       System.out.println("这是第1个拦截器,preHandle方法");
    
                       return false;
    
             }
    
            
    
             /**
    
              *  进入handler之后,返回modelandview之前执行
    
              *  应用场景从modelandview出发,将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图
    
              */
    
             @Override
    
             public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    
                                throws Exception {
    
                       // TODO Auto-generated method stub
    
                       System.out.println("这是第1个拦截器,postHandle方法");
    
                      
    
             }
    
     
    
             /**
    
              *  执行handler完成执行此方法
    
              *  应用场景:统一异常处理,统一日志处理
    
              */
    
             @Override
    
             public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    
                                throws Exception {
    
                       // TODO Auto-generated method stub
    
                       System.out.println("这是第1个拦截器, afterCompletion方法");
    
                      
    
             }
    
            
    
     
    
    }
    View Code

    两个拦截器都放行

    将两个return都改为true

    在浏览器中随意访问一个路由看效果:

    这是第1个拦截器,preHandle方法

    这是第2个拦截器,preHandle方法

    这是第2个拦截器,postHandle方法

    这是第1个拦截器,postHandle方法

    这是第2个拦截器,afterCompletion方法

    这是第1个拦截器, afterCompletion方法

    总结:

    preHandle方法按顺序执行

    postHandle方法和afterCompletion方法按拦截器配置的逆向顺序执行

    拦截器1放行,拦截器2不放行

    结果:

    这是第1个拦截器,preHandle方法

    这是第2个拦截器,preHandle方法

    这是第1个拦截器, afterCompletion方法

    总结:

    拦截器1放行,拦截器的preHandle方法才会执行

    拦截器2的preHandle方法不放行,拦截器2的postHandle方法和afterCompletion方法不会执行。

    只要有一个拦截器拦截不放行postHandle方法都不会执行

    拦截器1不放行,拦截器2不放行

    结果:

    这是第1个拦截器,preHandle方法

    总结:

    拦截器1 preHandle方法不放行,postHandle方法和afterCompletion方法都不会执行

    拦截器1 preHandle方法不放行,拦截器2不执行。

    小结

    根据测试结果,对拦截器应用。

    比如:

    统一日志处理拦截器,需要该拦截器preHandler一定要放行,且将它放在拦截器链接中的第一个位置。

    登录认证的拦截器,放在拦截器链接中的第一个位置

    权限校验拦截器,放在登录校验拦截器之后。(因为登录通过后才校验权限)

    拦截器的应用(实现登录认证)

    需求

    1、  用户请求URL

    2、  拦截器进行校验

    如果请求的URL是公开地址(无需登录就能访问的URL),让放行。、

    如果用户session不存在跳转到登录界面

    如果用户session存在,继续操作

    登录的controller方法

    package com.jch.controller;
    
     
    
    import javax.servlet.http.HttpSession;
    
     
    
    import org.springframework.stereotype.Controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    
     
    
    @Controller
    
    public class LoginController {
    
             // 登录
    
             @RequestMapping("login.jch")
    
             public String login(HttpSession session , String username , String password) {
    
                       // 调用service进行用户身份验证
    
                       // ...这里假设验证通过
    
                      
    
                       // 在session中保存用户身份信息
    
                       session.setAttribute("username", username);
    
                       return "redirect:/register.jch"; // /为项目根目录
    
             }
    
            
    
             // 退出登录
    
             @RequestMapping("logout.jch")
    
             public String login(HttpSession session) {
    
                      
    
                       // 清楚session数据
    
                       session.invalidate();
    
                       return "redirect:/login.jch";
    
             }
    
     
    
    }
    View Code

    登录认证拦截的实现

    代码实现

    package com.jch.interceptor;
    
     
    
    import javax.servlet.http.HttpServletRequest;
    
    import javax.servlet.http.HttpServletResponse;
    
    import javax.servlet.http.HttpSession;
    
     
    
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import org.springframework.web.servlet.ModelAndView;
    
     
    
     
    
    public class LoginInterceptor implements HandlerInterceptor{
    
     
    
             /**
    
              *  进入handler方法之前执行
    
              *  用于身份认证,身份校验
    
              *  比如身份认证,如果认证不通过表示当前用户没有登录,需要此方法拦截不在向下执行
    
              */
    
             @Override
    
             public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
                       // TODO Auto-generated method stub
    
                       // 获取请求的URL
    
                       String url = request.getRequestURI();
    
                       // 判断是否是公开地址(实际使用将公开地址配置在配置文件中)这里公开地址就是登录提交的地址
    
                       if(url.indexOf("login.jch")>=0) {
    
                                // 如果要登录提交,那么放行
    
                                return true;
    
                       }
    
                       // 判断session
    
                       HttpSession session = request.getSession();
    
                       String username = (String)session.getAttribute("username");
    
                       if(username != null) {
    
                                // 有身份信息,放行
    
                                return true;
    
                       }
    
                      
    
                       // 身份验证不通过跳转到登录界面
    
                       request.getRequestDispatcher("/views/home/login.jsp").forward(request, response);
    
                       System.out.println("这是第1个拦截器,preHandle方法");
    
                       return false;
    
             }
    
            
    
             /**
    
              *  进入handler之后,返回modelandview之前执行
    
              *  应用场景从modelandview出发,将共用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一制定视图
    
              */
    
             @Override
    
             public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
    
                                throws Exception {
    
                       // TODO Auto-generated method stub
    
                       System.out.println("这是第1个拦截器,postHandle方法");
    
                      
    
             }
    
     
    
             /**
    
              *  执行handler完成执行此方法
    
              *  应用场景:统一异常处理,统一日志处理
    
              */
    
             @Override
    
             public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
    
                                throws Exception {
    
                       // TODO Auto-generated method stub
    
                       System.out.println("这是第1个拦截器, afterCompletion方法");
    
                      
    
             }
    
            
    
     
    
    }
    View Code

    配置拦截器

    在springmvc的前端控制器配置文件中配置interceptor拦截器

    <!-- 配置拦截器 -->
    
                     <mvc:interceptors>
    
                     <!-- 多个拦截器,顺序执行 -->
    
                               <!-- 登录认证拦截器 -->
    
                               <mvc:interceptor>
    
                                        <mvc:mapping path="/**"/><!-- 标识拦截所有的URL包括所有的子URL -->
    
                                        <bean class="com.jch.interceptor.LoginInterceptor"></bean>
    
                               </mvc:interceptor>
    
                     </mvc:interceptors>
    View Code

    启动Tomcat查看测试结果。

  • 相关阅读:
    我渴望自由和成功(愿与君共勉)
    gdb使用 和core dump文件调试
    谷歌浏览器快捷键大全
    Android适屏
    BestCoder Round #33
    NAT&amp;Port Forwarding&amp;Port Triggering
    程序员应该学习的书
    java代码调用rtx发送提醒消息
    js实现excel导出
    一个跨界程序员:不务正业的这几年,我如何让自己的收入翻了十倍(转)
  • 原文地址:https://www.cnblogs.com/blogs-jch/p/11322550.html
Copyright © 2011-2022 走看看