Java项目微服务中添加拦截器实现

版权声明: https://blog.csdn.net/qq_23329167/article/details/83754749

目的:项目中需要拦截器的实现,让没有登陆的用户无法通过url来实现页面的渲染。

实现:

一、继承HandlerInterceptorAdapter

public class LoginInterceptor extends HandlerInterceptorAdapter

二、重写preHandler和afterCompletion

preHandler:前置方法,可以拦截在controller之前,return false被拦截,return true被放行

afterCompletion:完成方法,当视图渲染完成之后执行

/**
 * 前置方法:在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();
}

三、使用ThreadLocal共享用户信息数据UserInfo

设置到ThreadLocal中在后续的业务逻辑中就可以使用UserInfo数据

private static final ThreadLocal<UserInfo> THREAD_LOCAL = new ThreadLocal<>();

THREAD_LOCAL.set(userInfo);

完整的拦截器代码:

@EnableConfigurationProperties(JwtProperties.class)
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    private static final ThreadLocal<UserInfo> THREAD_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方法:

@Override
public void addInterceptors(InterceptorRegistry registry)

五、添加拦截器和拦截路径

@Override
public 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("/**");
    }
}

猜你喜欢

转载自blog.csdn.net/qq_23329167/article/details/83754749
今日推荐