本文共 4199 字,大约阅读时间需要 13 分钟。
目的:项目中需要拦截器的实现,让没有登陆的用户无法通过url来实现页面的渲染。
实现:
public class LoginInterceptor extends HandlerInterceptorAdapter
preHandler:前置方法,可以拦截在controller之前,return false被拦截,return true被放行
afterCompletion:完成方法,当视图渲染完成之后执行
/** * 前置方法:在handler方法执行之前执行 * false-被拦截 * true-放行 * @param request * @param response * @param handler * @throws Exception */@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取token信息 String token = CookieUtils.getCookieValue(request, this.jwtProperties.getCookieName()); // 判断token是否为空 if (StringUtils.isBlank(token)) { // 没有登录,跳转到登录页 response.sendRedirect("登陆页面的url(从上个页面进入登陆页面的url)"); return false; } // 解析jwt UserInfo userInfo = JwtUtils.getInfoFromToken(token, this.jwtProperties.getPublicKey()); if (userInfo == null) { response.sendRedirect("登陆页面的url(从上个页面进入登陆页面的url)"); return false; } THREAD_LOCAL.set(userInfo); return true;}/** * 完成方法:在视图渲染完成之后执行 * @param request * @param response * @param handler * @param ex * @throws Exception */@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 必须要释放资源,使用的是tomcat线程池,业务逻辑处理完成之后,线程并没有结束,还回到线程池中了 THREAD_LOCAL.remove();}
设置到ThreadLocal中在后续的业务逻辑中就可以使用UserInfo数据
private static final ThreadLocalTHREAD_LOCAL = new ThreadLocal<>();THREAD_LOCAL.set(userInfo);
@EnableConfigurationProperties(JwtProperties.class)@Componentpublic class LoginInterceptor extends HandlerInterceptorAdapter { private static final ThreadLocalTHREAD_LOCAL = new ThreadLocal<>(); public LoginInterceptor(JwtProperties jwtProperties) { this.jwtProperties = jwtProperties; } @Autowired private JwtProperties jwtProperties; /** * 前置方法:在handler方法执行之前执行 * false-被拦截 * true-放行 * @param request * @param response * @param handler * @throws Exception */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 获取token信息 String token = CookieUtils.getCookieValue(request, this.jwtProperties.getCookieName()); // 判断token是否为空 if (StringUtils.isBlank(token)) { // 没有登录,跳转到登录页 response.sendRedirect("登陆页面的url(从上个页面进入登陆页面的url)"); return false; } // 解析jwt UserInfo userInfo = JwtUtils.getInfoFromToken(token, this.jwtProperties.getPublicKey()); if (userInfo == null) { response.sendRedirect("登陆页面的url(从上个页面进入登陆页面的url)"); return false; } THREAD_LOCAL.set(userInfo); return true; } /** * 完成方法:在视图渲染完成之后执行 * @param request * @param response * @param handler * @param ex * @throws Exception */ @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 必须要释放资源,使用的是tomcat线程池,业务逻辑处理完成之后,线程并没有结束,还回到线程池中了 THREAD_LOCAL.remove(); } /** * 获取线程变量中的参数 * @return */ public static UserInfo get() { return THREAD_LOCAL.get(); }}
两个条件:1、实现WebMvcConfigurer接口 2、添加@Configuration注解
重写addInterceptors方法:
@Overridepublic void addInterceptors(InterceptorRegistry registry)
@Overridepublic void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor()).addPathPatterns("/**");}
其中的addPathPatterns("/**")是指拦截所有的路径
@Configuration@EnableConfigurationProperties(JwtProperties.class)public class ProjectConfig implements WebMvcConfigurer { @Autowired private JwtProperties jwtProperties; @Bean public LoginInterceptor loginInterceptor() { return new LoginInterceptor(jwtProperties); } /** * 注册拦截器到拦截器注册器中,使拦截器生效 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor()).addPathPatterns("/**"); }}
转载地址:http://sffjn.baihongyu.com/