springboot自定义拦截器的方法
程序员文章站
2022-03-04 13:35:33
拦截器应该分属于web框架的组件,每个框架提供的自己的支持,实现方式也就不同。例如struts和spring,以下是spring 的拦截器总结,它是基于动态代理(反射)实现的。spring 中声明拦截...
拦截器应该分属于web框架的组件,每个框架提供的自己的支持,实现方式也就不同。例如struts和spring,以下是spring 的拦截器总结,它是基于动态代理(反射)实现的。
spring 中声明拦截器需要实现 handlerinterceptor 接口,当然也可以通过继承handlerinterceptoradapter 抽象类,handlerinterceptoradapter也是实现了handlerinterceptor 接口。
拦截器中有四个方法:
prehandle:在controller中的方法之前执行,决定是否放行,return true表示放行。一旦放行其对应的aftercompletion就一定会执行。
posthandle:controller中的方法处理完之后,dispatcherservlet进行视图的渲染之前,也就是说在这个方法中你可以对modelandview进行操作
aftercompletion:dispatcherservlet进行视图的渲染之后
afterconcurrenthandlingstarted:与异步相关
下面通过代码实践,备注了是否放行和异常对拦截器内方法执行的影响结论。其实只需对方法执行的时机进行分析,我们就可以得出相同的结论。
如果想深入了解每个方法的执行时机,可以阅读springmvc的 dispatcherservlet 源码
@component public class interceptortwo extends handlerinterceptoradapter { /** * handler 对应@requestmapping对应的controller对象 */ @override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { //这里我们是没办法拿到方法参数的,parameters是空的,但是可以拿到controller种注入的bean //可以断点验证 handlermethod handlermethod = (handlermethod)handler; methodparameter [] parameters = handlermethod.getmethodparameters(); return true;//放行 } @override public void posthandle(httpservletrequest request, httpservletresponse response, object handler, modelandview modelandview) throws exception { //在拦截器链中,只要有一个不放行的,所有的posthandle都不会执行 //如果controller方法抛异常了,所有的posthandle也不会执行 system.out.println("posthandle"); } @override public void aftercompletion(httpservletrequest request, httpservletresponse response, object handler, exception ex) throws exception { //只要对应的prehandle放行了就一定会执行,controller方法抛异常也不会影响 system.out.println("aftercompletion"); } @override public void afterconcurrenthandlingstarted(httpservletrequest request, httpservletresponse response, object handler) throws exception { system.out.println("afterconcurrenthandlingstarted"); } }
使拦截器生效
//springboot 是1.x版本的项目中是extends webmvcconfigureradapter ,代码也是一样的 @configuration public class interceptorconfig implements webmvcconfigurer { @autowired private sourceaccessinterceptor interceptor; @autowired private interceptorone interceptorone; @override public void addinterceptors(interceptorregistry interceptorregistry) { //1.加入的顺序就是拦截器执行的顺序,设置@order也不会影响 //2.按顺序执行所有拦截器的prehandle //3.所有的prehandle 执行完再反向执行全部posthandle 最后是反向执行aftercompletion, //如果其中有一个未放行,或者抛异常了会影响执行顺序吗?怎样影响 interceptorregistry.addinterceptor(interceptor).addpathpatterns("/**"); interceptorregistry.addinterceptor(interceptorone); } }
应用示例
这个拦截器是用来拦截请求是否有携带token的,如果请求未携带token,将会302重定向到登录界面。
@component public class authinterceptor extends handlerinterceptoradapter { @autowired private jwtutil jwtutil; @value("${login.url}") private string loginurl; /** * 验证access_token * * @param request 请求 * @param response 响应 * @param handler 处理器controller */ @override public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception { handlermethod handlermethod = (handlermethod) handler; //withouttoken是我自定义的注解,标注在方法上,表示不需要验证token if (handlermethod.getmethod().isannotationpresent(withouttoken.class)) { //不需要验证token return true; } else { try { //校验jwt string access_token = request.getheader("access_token"); jwtutil.verifiertoken(access_token); //获取用户信息 final string account = jwtutil.getaccount(access_token); //todo 可以在这里查询用户信息,然后将用户信息设置到线程变量 } catch (nullpointerexception | jwtverificationexception e) { //todo 重定向到登陆页 response.sendredirect(loginurl); return false; } return true; } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读