springboot自定义拦截器的方法

网友投稿 605 2022-09-05


springboot自定义拦截器的方法

拦截器应该分属于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, SpGJqxvZVHttpServletResponse response, Object handler, Exception ex) throws Exception {

//只要对应的preHandle放行了就一定会执行,Conhttp://troller方法抛异常也不会影响

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 处理器controlleSpGJqxvZVr

*/

@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;

}

}

}SpGJqxvZV


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【SVM分类】基于粒子群算法优化支持向量机实现葡萄酒数据分类附matlab代码
下一篇:【樽海鞘算法】基于集成随机惯性权重和差分变异操作的樽海鞘群算法(ISSA)求解单目标问题附matlab代码
相关文章

 发表评论

暂时没有评论,来抢沙发吧~