Spring MVC拦截器(Interceptor)使用

  先上结论图:

               

   错误案例:

    需求:登录页面,验证用户是否有访问权限。拦截器验证该用户是否已登录,如已登录可继续访问,如未登录进入登录页面。基础代码参考Spring Boot Web项目整合jsp页面访问(非web项目改为web项目适用) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)

    在登录的基础上增加拦截器校验用户是否已登录功能(登录了session一直存在),具体实现如下:

    一、请求拦截器实现,普通的Bean通过实现HandlerInterceptor接口可自定义拦截器

      看下这个接口的定义,其声明了三个方法,分别对应上图中三次拦截点:

        

       根据需求,我们使用的只有第一个方法preHandler,即在进入任何页面前判断登录状态。@Controler中控制了页面的跳转。具体拦截器实现如下

              

     二、Web配置,通过实现WebMvcConfigurer的addInterceptors方法注册定义拦截器,实现如下:

              

     三、运行

      首先,在没有拦截器的情况下看实现效果:

              

       通过上图路由映射,这个servlet控制进入login.jsp页面

              

       输入用户名、密码后页面跳转失败:

              

       为什么?看控制台输出

              

               

     空指针问题,就是没有取到输入的用户名(为什么没有取到用户名,是另外一个问题,这里不讨论)。那么如果有拦截器,猜猜什么效果呢?应该是遇到此类情景重新跳转至登录页面。

    那自定义的拦截器有没有实现呢?看添加拦截器后的效果

              

    看控制台信息:

              

     一直在提示请登录为什么呢?这个就与开始提供的Interceptor与@Controller之间执行的时序有关系了。

    分析:

      @Controller("tologin")这个控制进入login.jsp登录界面,在其执行前interceptor先判断这个用户是否存在——也就是说还没有进入登录界面,就会一直提示需要进入登录界面重新跳转到tologin,但是tologin又需要等待interceptor放行让可执行,进而陷入死循环,是不是就是死锁的意思。

    那么怎么解决呢?排除login下的所有servlet,即仅非登录相关的servlet使用拦截器,如下: 

              

     验证与不使用拦截器效果一样:

              

    四、解决获取session相关属性值的问题后(参考Spring MVC参数绑定(如何接收请求参数及返回参数) - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)),跟踪拦截器作用点:

      增加一个@Controller类

             

       注意login相关controller中关于重定向的编码:

             

    下面是跟踪调试结果:

      1、合法用户:

            

       2、非法用户:

             

补充说明一下配置页面跳转快捷重定向的ViewController:

            

  对于没有业务逻辑,只是简单页面跳转的@RequestMapping,可以考虑使用ViewController实现页面跳转简化配置,如下代码:

    @RequestMapping("/index")

    public String Hello(){

      return "index";

    }

  对于有复杂业务逻辑的方法,可以在实现了WebMvcConfigurer的配置类中,添加页面跳转简化业务方法:

             

 

posted on 2021-05-06 16:18  池塘里洗澡的鸭子  阅读(342)  评论(0编辑  收藏  举报