Java Httpclient HttpRequestRetryHandler 不起作用。如何实现重试?

发布于 2024-11-09 17:42:53 字数 5211 浏览 0 评论 0 原文

我正在尝试在未收到响应后实施请求重试。 我在 Httpclient 教程中读到了它。 HttpRequestRetryHandler 仅被调用一次,然后抛出异常。我在这里做错了什么?

已更新
我在 SocketTimeoutException 的异常处理中添加了一个 if 条件。
但接下来该怎么办呢?我该如何重试?

private void setRetry(int executionCount)
{
    myRetryHandler = new HttpRequestRetryHandler() {

        public boolean retryRequest(IOException exception,int executionCount,HttpContext context) {

            if (executionCount >= 4) {
                // Do not retry if over max retry count
                System.out.println("retry count");
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                System.out.println("NoHttpResponseException exception");// Retry if the server dropped connection on us
                return true;
            }
            if (exception instanceof SSLHandshakeException) {
                // Do not retry on SSL handshake exception
                System.out.println("SSLHandshakeException exception");
                return false;
            }
            if (exception instanceof java.net.SocketTimeoutException) {
              // Do not retry on SSL handshake exception
              System.out.println("java.net.SocketTimeoutException exception");
              return false;
            }
            HttpRequest request = (HttpRequest) context.getAttribute( ExecutionContext.HTTP_REQUEST);
            boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); 
            if (idempotent) {
                System.out.println("idempotent exception");
                // Retry if the request is considered idempotent 
                return true;
            }
            return false;
        }
    };
}
public  String postHttpReqest(int retries,
                              int socketTimeoutMillis,
                              int isSSL,
                              String target,
                              String url,
                              String base_url,
                              int port,
                              LinkedHashMap<String, String> lHashMapParams) throws Exception 
{


    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, 50000);
    HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);         
    defaulthttpclient = new DefaultHttpClient(httpParams);

    setRetry(retries);  // here i set the handler 
    defaulthttpclient.setHttpRequestRetryHandler(myRetryHandler);

    String line = "";

    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
    for (String key : lHashMapParams.keySet()) {
        String val = lHashMapParams.get(key);
        params.add(new BasicNameValuePair(key,val));

    }

    UrlEncodedFormEntity query = new UrlEncodedFormEntity(params); 
    HttpPost httppost = new HttpPost(url+":"+Integer.toString(port)+"//"+base_url);
    httppost.setEntity(query);
    HttpResponse response_ = defaulthttpclient.execute(httppost);
    HttpEntity entity = response_.getEntity();

    if (entity != null) {
        line = EntityUtils.toString(entity);
        System.out.println(line);

    }

    return line;
}

在服务器中,我设置了断点,因此它将保持连接并且不会返回响应。 我在 Httpclient 中遇到的错误:

java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:149)
    at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:110)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:260)
    at org.apache.http.impl.conn.LoggingSessionInputBuffer.readLine(LoggingSessionInputBuffer.java:115)
    at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:98)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:252)
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:281)
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:247)
    at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:219)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:298)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:633)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:454)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
    at com.fts.lb.connector.ut.HttpClientImpl.postHttpReqest(HttpClientImpl.java:183)

I am trying to implement request retries after response isn't received.
I was reading about it in the Httpclient tutorial. the HttpRequestRetryHandler gets invoked only once and then it throw exception . what do I do wrong here?

updated
I added one if condition in the exception handling for SocketTimeoutException.
but what to do from there? how can I retry?

private void setRetry(int executionCount)
{
    myRetryHandler = new HttpRequestRetryHandler() {

        public boolean retryRequest(IOException exception,int executionCount,HttpContext context) {

            if (executionCount >= 4) {
                // Do not retry if over max retry count
                System.out.println("retry count");
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                System.out.println("NoHttpResponseException exception");// Retry if the server dropped connection on us
                return true;
            }
            if (exception instanceof SSLHandshakeException) {
                // Do not retry on SSL handshake exception
                System.out.println("SSLHandshakeException exception");
                return false;
            }
            if (exception instanceof java.net.SocketTimeoutException) {
              // Do not retry on SSL handshake exception
              System.out.println("java.net.SocketTimeoutException exception");
              return false;
            }
            HttpRequest request = (HttpRequest) context.getAttribute( ExecutionContext.HTTP_REQUEST);
            boolean idempotent = !(request instanceof HttpEntityEnclosingRequest); 
            if (idempotent) {
                System.out.println("idempotent exception");
                // Retry if the request is considered idempotent 
                return true;
            }
            return false;
        }
    };
}
public  String postHttpReqest(int retries,
                              int socketTimeoutMillis,
                              int isSSL,
                              String target,
                              String url,
                              String base_url,
                              int port,
                              LinkedHashMap<String, String> lHashMapParams) throws Exception 
{


    HttpParams httpParams = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(httpParams, 50000);
    HttpConnectionParams.setSoTimeout(httpParams, socketTimeoutMillis);         
    defaulthttpclient = new DefaultHttpClient(httpParams);

    setRetry(retries);  // here i set the handler 
    defaulthttpclient.setHttpRequestRetryHandler(myRetryHandler);

    String line = "";

    List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
    for (String key : lHashMapParams.keySet()) {
        String val = lHashMapParams.get(key);
        params.add(new BasicNameValuePair(key,val));

    }

    UrlEncodedFormEntity query = new UrlEncodedFormEntity(params); 
    HttpPost httppost = new HttpPost(url+":"+Integer.toString(port)+"//"+base_url);
    httppost.setEntity(query);
    HttpResponse response_ = defaulthttpclient.execute(httppost);
    HttpEntity entity = response_.getEntity();

    if (entity != null) {
        line = EntityUtils.toString(entity);
        System.out.println(line);

    }

    return line;
}

In the server, I set break point so it will hold the connection and will not return response.
The error I am getting in the Httpclient :

java.net.SocketTimeoutException: Read timed out
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(SocketInputStream.java:129)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:149)
    at org.apache.http.impl.io.SocketInputBuffer.fillBuffer(SocketInputBuffer.java:110)
    at org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:260)
    at org.apache.http.impl.conn.LoggingSessionInputBuffer.readLine(LoggingSessionInputBuffer.java:115)
    at org.apache.http.impl.conn.DefaultResponseParser.parseHead(DefaultResponseParser.java:98)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:252)
    at org.apache.http.impl.AbstractHttpClientConnection.receiveResponseHeader(AbstractHttpClientConnection.java:281)
    at org.apache.http.impl.conn.DefaultClientConnection.receiveResponseHeader(DefaultClientConnection.java:247)
    at org.apache.http.impl.conn.AbstractClientConnAdapter.receiveResponseHeader(AbstractClientConnAdapter.java:219)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:298)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
    at org.apache.http.impl.client.DefaultRequestDirector.tryExecute(DefaultRequestDirector.java:633)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:454)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732)
    at com.fts.lb.connector.ut.HttpClientImpl.postHttpReqest(HttpClientImpl.java:183)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

好听的两个字的网名 2024-11-16 17:42:53

嗯..您的 RetryHandler 专门为 SocketTimeoutException 返回 false。
所以我希望它 100% 的时间都会抛出异常,事实确实如此。

如果您希望在客户端在收到响应之前超时时重试请求,那么您需要让 RetyrHandler 对 SocketTimeOutExceptions 返回 true。您可能还想在重试之前增加 SocketTimeOut。

Um .. your RetryHandler is specifically returning false for a SocketTimeoutException.
So I would expect it to throw an Exception 100% of the time, which it is.

If you want the Request to be retried when the client times out before receiving a response, then you need to have your RetyrHandler return true for SocketTimeOutExceptions. You might also want to increase your SocketTimeOut before retrying.

只为守护你 2024-11-16 17:42:53

Googlein了一下我发现了这个 bug(仅在 Windows 上)。

对于我的问题,我已经使用最新的 4.1.1,但也许我必须实现 retryHandler。

我希望这会有所帮助。

Googlein a little bit I found this bug in the HttpClient 4.1 client (only on Windows).

For my problem I already use the latest 4.1.1, but maybe I have to implement the retryHandler.

I hope it will be helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文