多个RestTemplate使用不同的拦截器+无拦截器的配置

最近有个需求,调用某服务器API时,先从服务器取得token,token取得失败再使用账密重试,这里还要求使用拦截器处理.

那么问题来了,对RestTemplate拦截的话,会导致我从服务器取得token也被拦截,如何能跳过取token的请求呢?

有一个方法就是直接在拦截器中根据获取token的请求路径来判断,但当有多个不同的服务器token要跳过的话,代码很臃肿,不易于理解.

解决办法:使用构造器注入

在需要调用API的地方注入带有拦截器的RestTemplate();拦截器中使用 new RestTemplate()中来取得token.

WebSecurityConfig.java配置

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    ...
    ...

    @Bean
    public ServiceAProxy serviceAProxy() throws Exception {
        // A服务类注入带有拦截器A的RestTemplate()
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setInterceptors(Collections.singletonList(myInterceptorA()));
        // 构造器注入
        return new ServiceAProxy(restTemplate);
    }

    @Bean
    public MyInterceptorAmyInterceptorA() throws Exception {
        // 拦截器A中直接使用new RestTemplate()获取token
        return new MyInterceptorAmyInterceptorA();
    }

    @Bean
    public ServiceBProxy serviceBProxy() throws Exception {
        // B服务类注入带有拦截器B的RestTemplate()
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setInterceptors(Collections.singletonList(myInterceptorB()));
        // 构造器注入
        return new ServiceBProxy(restTemplate);
    }

    @Bean
    public MyInterceptorAmyInterceptorB() throws Exception {
        // 拦截器B中直接使用new RestTemplate()获取token
        return new MyInterceptorAmyInterceptorB();
    }
}

ServiceAProxy

public class ServiceAProxy {

    /**
     * RestTemplate
     */
    private RestTemplate restTemplate;

    // 构造器注入
    @Autowired
    public ServiceAProxy(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    ...
}

MyInterceptorA

public class MyInterceptorA implements ClientHttpRequestInterceptor {

   
    /**
     * RestTemplate
     */
    private RestTemplate restTemplate = new RestTemplate();

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException {
        // Head
        HttpHeaders requestHeaders = request.getHeaders();

        var accesstoken = tokenService.getToekn(ACCESSTOKEN_ID);

        requestHeaders.set("content-type", "application/json");
        requestHeaders.add(apiKeys, apiValue);
        requestHeaders.add("Authorization", "Bearer " + accesstoken);

        var response = execution.execute(request, body);
        // 不是认证错误则退出
        if (HttpStatus.UNAUTHORIZED != response.getStatusCode()) {
            return response;
        }

        // 第一次认证错误时,使用刷新Token重试
        var accessToken = getRefreshToekn();
        if (!Strings.isEmpty(accessToken)) {
            requestHeaders.set("Authorization", "Bearer " + accessToken);
            response = execution.execute(request, body);
            // 不是认证错误则退出
            if (HttpStatus.UNAUTHORIZED != response.getStatusCode()) {
                return response;
            }
        }

        // 第二次认证错误使用账户密码重新取得token 
        accessToken = getToeknByUserPassWord();

        requestHeaders.set("Authorization", "Bearer " + accessToken);
        response = execution.execute(request, body);

        return response;

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值