HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() { public boolean retryRequest( IOException exception, int executionCount, HttpContext context) { if (executionCount >= 5) { // Do not retry if over max retry count return false; } if (exception instanceof InterruptedIOException) { // Timeout return false; } if (exception instanceof UnknownHostException) { // Unknown host return false; } if (exception instanceof ConnectTimeoutException) { // Connection refused return false; } if (exception instanceof SSLException) { // SSL handshake exception return false; } HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); if (idempotent) { // Retry if the request is considered idempotent return true; } return false; } }; CloseableHttpClient httpclient = HttpClients.custom() .setRetryHandler(myRetryHandler) .build();
https://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html
不知道有多少人在重写HttpRequestRetryHandler 的时候直接copy了官网的这段代码,然后修改
结果综合测试里,get可以retry没问题,post死活过不了
查了几个小时后,终于发现在1.4.2里有以下说明
HttpClient assumes non-entity enclosing methods such as GET
and HEAD
to be idempotent and entity enclosing methods such as POST
and PUT
to be not.
一切恍然大悟
删掉以下代码,直接返回true进行retry即可
HttpClientContext clientContext = HttpClientContext.adapt(context); HttpRequest request = clientContext.getRequest(); boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); if (idempotent) {