欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringMVC-拦截器做一个登录认证的小Demo

程序员文章站 2022-06-05 20:22:48
拦截器 拦截器的定义 处理器拦截器类似于servlet开发中的filter,用于对处理器进行预处理和后处理。 定义拦截器,实现HandlerInterceptor这个接口 接口的实现需要导入包import org.springframework.web.servlet.HandlerIntercep ......

拦截器

 

拦截器的定义

处理器拦截器类似于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

                  

         }

        

 

}

拦截器的配置

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方法");

                  

         }

        

 

}

 

 

两个拦截器都放行

将两个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";

         }

 

}

 

 

登录认证拦截的实现

代码实现

 

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方法");

                  

         }

        

 

}

 

配置拦截器

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

 

<!-- 配置拦截器 -->

                 <mvc:interceptors>

                 <!-- 多个拦截器,顺序执行 -->

                           <!-- 登录认证拦截器 -->

                           <mvc:interceptor>

                                    <mvc:mapping path="/**"/><!-- 标识拦截所有的url包括所有的子url -->

                                    <bean class="com.jch.interceptor.logininterceptor"></bean>

                           </mvc:interceptor>

                 </mvc:interceptors>

启动tomcat查看测试结果。