问题描述
处理特定的网站,有时我会收到状态码为 403 的 http 响应.我想在这种情况下重新执行请求(因为,在我的特定情况下,该服务器在实际过载时会抛出 403).我尝试将 ResponseHandler
与 StandardHttpRequestRetryHandler
一起使用,但它没有按我希望的方式工作;我预计在 ResponseHandler
中抛出异常会触发 StandardHttpRequestRetryHandler
,但似乎并非如此.我如何才能实现所需的功能?
Dealing with a specific website, sometimes I receive a http response with status code 403. I wanted to re-execute the request in such cases (because, in my specific situation, this server throws a 403 when it is actually overloaded). I tried to use a ResponseHandler
together with a StandardHttpRequestRetryHandler
, but it didn't work the way I hoped; I expected that throwing an exception in the ResponseHandler
would trigger the StandardHttpRequestRetryHandler
, but it does not seems to be the case. How can I achieve the desired functionality?
这是一个示例代码,说明了我的情况:
Here is a sample code that illustrates my situation:
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
public class Main {
public static void main(String[] args) throws Exception {
// a response handler that throws an exception if status is not 200
ResponseHandler<String> responseHandler = new ResponseHandler<String> () {
@Override
public String handleResponse(HttpResponse response) throws
ClientProtocolException, IOException
{
System.out.println("-> Handling response");
if (response.getStatusLine().getStatusCode() != 200){
// I expected this to trigger the retryHandler
throw new ClientProtocolException("Status code not supported");
}
return EntityUtils.toString(response.getEntity());
}
};
StandardHttpRequestRetryHandler retryHandler =
new StandardHttpRequestRetryHandler(5, true)
{
@Override
public boolean retryRequest(
final IOException exception,
final int executionCount,
final HttpContext context)
{
System.out.println("-> Retrying request");
return super.retryRequest(exception, executionCount, context);
}
};
// my client with my retry handler
HttpClient client = HttpClients
.custom()
.setRetryHandler(retryHandler)
.build();
// my request
HttpUriRequest request = RequestBuilder
.create("GET")
.setUri("http://httpstat.us/403") //always returns 403
.build();
String contents = client.execute(request, responseHandler);
System.out.println(contents);
}
}
推荐答案
尝试使用自定义 ServiceUnavailableRetryStrategy
CloseableHttpClient client = HttpClients.custom()
.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
@Override
public boolean retryRequest(
final HttpResponse response, final int executionCount, final HttpContext context) {
int statusCode = response.getStatusLine().getStatusCode();
return statusCode == 403 && executionCount < 5;
}
@Override
public long getRetryInterval() {
return 0;
}
})
.build();
这篇关于强制重试特定的 http 状态代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!