ThreadLocal在拦截器中的使用

发布时间 2023-05-29 14:47:31作者: 做时间的好朋友

前置过滤捕获,写入context中,后置删除

每个request请求都有自己线程独享的数据,所以用到了ThreadLocal

1.添加拦截器

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new IdentityInterceptor())
                .addPathPatterns("/**");
    }
}

2.拦截器定义

@Slf4j
@Component
public class IdentityInterceptor implements HandlerInterceptor {

    /*
    根据HttpHeader中的roleType判断用户身份
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        var identityStr = request.getHeader("roleType");
        var loginContext = LoginContext.getLoginContext();

        var pin = loginContext != null ? loginContext.getPin() : null;
        Identity identity;
        if (Strings.isNullOrEmpty(identityStr) ||
                !Enums.getIfPresent(IdentityType.class, identityStr).isPresent()) {
            log.warn("Identity:[{}] not found,use default identity instead.url:{}, User:{}", identityStr, request.getRequestURL(), pin);
            identity = Identity.DEFAULT_IDENTITY;
        } else {
            identity = new Identity(identityStr);
        }
        Identity.setIdentity(identity); // 核心是这个,写入用户角色身份上下文
        log.info("RoleType:[{}],user:[{}]-Identity:[{}] for url:{}. ", identityStr, pin, identity.getIdentityType(), request.getRequestURL());

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

        log.info("remove Identity for [{}] from url {}"
                , Identity.getIdentity() == null ? "null" : Identity.getIdentity().getIdentityType()
                , request.getRequestURL());
        Identity.remove(); // 删除用户角色上下文数据
    }
}

3.Identity用户身份定义