Java中出现401错误代码时,自动登录并重试原始请求

时间:2019-07-19 05:50:04

标签: java apache-httpclient-4.x

我正在使用Apache HttpClient来使用API​​调用。

我们正在使用登录API调用并在所有其他API调用中将此令牌用作标头参数来获取登录令牌。 此登录令牌将在一段时间后过期,然后后续的API调用将返回401未经授权的错误。 我希望Apache HttpCleint可以检测到401错误并自动登录并重试原始API调用。

通过谷歌搜索,我发现了正是我所需要的链接。 Automatically retry on 401 and send specific request with HttpClient 4.3

我不能按照这里的建议使用OkHttpClient,但是这里建议的另一种解决方案是在HttpClient上编写一个Proxy类,该类捕获了“ execute”方法的结果。 我不知道如何执行此操作。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

您的代码中可以有一个类似MyHttpClient的类,它实现了HttpClient接口。它可以使用装饰器模式,这意味着它将拥有真实HttpClient类的内部实例,并将其几乎所有方法调用委托给该类。

public class MyHttpClient implements HttpClient {
    private HttpClient httpClient;
    private String signinToken = ""

    public MyHttpClient() {
        this.httpClient = HttpClient5Factory.createHttpClient();
        this.signinToken = SigninTokenProvider.getToken();
    }

    @Override
    public HttpParams getParams() {
        return this.httpClient.getParams();
    }

    @Override
    public ClientConnectionManager getConnectionManager() {
        return this.httpClient.getConnectionManager();
    }

    ...
}

然后,您可以实现在此类中获取登录标头的逻辑,或者,如果您在其他类别中具有登录标头,则此类可以在需要时调用它们以刷新登录令牌。我认为在此类中添加登录标头要有意义得多,这样您就可以将登录处理放在一个地方。

execute方法的实现中,您应该具有如下代码:

@Override
public HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {

    //  add signin header to each request
    request.addHeader(new BasicHeader("Authorization", this.signinToken));

    HttpResponse response = httpClient.execute(request);
    if(response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
        //  do the authentication process again
        this.signinToken = SigninTokenProvider.getToken();
        request.removeHeader("Authorization");
        request.addHeader(new BasicHeader("Authorization", this.signinToken));

        //  resend the request
        response = httpClient.execute(request);
    }

    return response;
}

如您所见,您可以调用实际的API并检查响应状态。如果是401,则可以重做身份验证过程并获取新的登录值,然后使用新的登录值重试请求。