处理特定网站时,有时我会收到状态代码为403的http响应.我想在这种情况下重新执行请求(因为,在我的特定情况下,此服务器在实际超载时会抛出403).我尝试将ResponseHandler与StandardHttpRequestRetryHandler一起使用,但它没有按照我希望的方式工作;我期望在ResponseHandler中抛出异常会触发StandardHttpRequestRetryHandler,但似乎并非如此.如何实现所需的功能?
这是一个示例代码,说明了我的情况:
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 HttpContext context) { int statusCode = response.getStatusLine().getStatusCode(); return statusCode == 403 && executionCount < 5; } @Override public long getRetryInterval() { return 0; } }) .build();