当前位置: 首页 > 知识库问答 >
问题:

让HttpClient在下一次请求之前消耗“垃圾”

唐弘益
2023-03-14

我正在使用Apache HttpClient 4.5.1向我们的服务器发送一些请求。为了提高性能,我想为所有这些请求重用同一个HttpClient实例。请求(大部分)是按顺序发生的,所以不涉及多线程

不幸的是,一些服务器的endpoint是错误的。他们返回一个HTTP 204(没有内容),但是在响应体中有一些数据。尽管这个问题在最新的版本中已经得到了解决,但是我们还需要处理旧版本一段时间。这种服务器行为导致HTTP客户端在下一次请求时“挂起”(/timeout)(请参阅使用Apache HTTPClient的每秒请求失败以获取详细信息)。

有没有办法在客户端解决这个问题?我试过这个

HttpEntity entity = response.getEntity();
if (null != entity) {
    EntityUtils.consumeQuietly(entity);
}

但是实体似乎为空,所以我无法使用连接套接字中的响应数据。有没有另一种方法可以在不丢弃HttpClient实例(及其HTTP连接)的情况下清理套接字?

客户端日志如下所示:

DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 90000
MainClientExec - Executing request DELETE /prod/update-rest/private/deleteGroup/AS123 HTTP/1.1
MainClientExec - Target auth state: UNCHALLENGED
MainClientExec - Proxy auth state: UNCHALLENGED
headers - http-outgoing-0 >> DELETE /prod/update-rest/private/deleteGroup/AS123 HTTP/1.1
headers - http-outgoing-0 >> Host: xyz
headers - http-outgoing-0 >> Connection: Keep-Alive
headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.1 (Java/1.7.0_79)
headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
wire - http-outgoing-0 >> "DELETE /prod/update-rest/private/deleteGroup/AS123 HTTP/1.1[\r][\n]"
wire - http-outgoing-0 >> "Host: xyz[\r][\n]"
wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.1 (Java/1.7.0_79)[\r][\n]"
wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
wire - http-outgoing-0 >> "[\r][\n]"
wire - http-outgoing-0 << "HTTP/1.1 401 Unauthorized[\r][\n]"
wire - http-outgoing-0 << "Date: Mon, 05 Oct 2015 13:30:35 GMT[\r][\n]"
wire - http-outgoing-0 << "Server: Apache/2.2.12 (Linux/SUSE)[\r][\n]"
wire - http-outgoing-0 << "Pragma: No-cache[\r][\n]"
wire - http-outgoing-0 << "Cache-Control: no-cache[\r][\n]"
wire - http-outgoing-0 << "Expires: Thu, 01 Jan 1970 01:00:00 CET[\r][\n]"
wire - http-outgoing-0 << "WWW-Authenticate: Basic realm="ApplicationRealm"[\r][\n]"
wire - http-outgoing-0 << "Content-Length: 958[\r][\n]"
wire - http-outgoing-0 << "Keep-Alive: timeout=15, max=100[\r][\n]"
wire - http-outgoing-0 << "Connection: Keep-Alive[\r][\n]"
wire - http-outgoing-0 << "Content-Type: text/html;charset=utf-8[\r][\n]"
wire - http-outgoing-0 << "[\r][\n]"
headers - http-outgoing-0 << HTTP/1.1 401 Unauthorized
headers - http-outgoing-0 << Date: Mon, 05 Oct 2015 13:30:35 GMT
headers - http-outgoing-0 << Server: Apache/2.2.12 (Linux/SUSE)
headers - http-outgoing-0 << Pragma: No-cache
headers - http-outgoing-0 << Cache-Control: no-cache
headers - http-outgoing-0 << Expires: Thu, 01 Jan 1970 01:00:00 CET
headers - http-outgoing-0 << WWW-Authenticate: Basic realm="ApplicationRealm"
headers - http-outgoing-0 << Content-Length: 958
headers - http-outgoing-0 << Keep-Alive: timeout=15, max=100
headers - http-outgoing-0 << Connection: Keep-Alive
headers - http-outgoing-0 << Content-Type: text/html;charset=utf-8
MainClientExec - Connection can be kept alive for 15000 MILLISECONDS
HttpAuthenticator - Authentication required
HttpAuthenticator - xyz:443 requested authentication
TargetAuthenticationStrategy - Authentication schemes in the order of preference: [Negotiate, Kerberos, NTLM, Digest, Basic]
TargetAuthenticationStrategy - Challenge for Negotiate authentication scheme not available
TargetAuthenticationStrategy - Challenge for Kerberos authentication scheme not available
TargetAuthenticationStrategy - Challenge for NTLM authentication scheme not available
TargetAuthenticationStrategy - Challenge for Digest authentication scheme not available
HttpAuthenticator - Selected authentication options: [BASIC [complete=true]]
wire - http-outgoing-0 << "<html><head><title>JBoss Web/7.0.13.Final - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 401 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Status report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>This request requires HTTP authentication ().</u></p><HR size="1" noshade="noshade"><h3>JBoss Web/7.0.13.Final</h3></body></html>"
DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 90000
MainClientExec - Executing request DELETE /prod/update-rest/private/deleteGroup/AS123 HTTP/1.1
MainClientExec - Target auth state: CHALLENGED
HttpAuthenticator - Generating response to an authentication challenge using basic scheme
MainClientExec - Proxy auth state: UNCHALLENGED
headers - http-outgoing-0 >> DELETE /prod/update-rest/private/deleteGroup/AS123 HTTP/1.1
headers - http-outgoing-0 >> Host: xyz
headers - http-outgoing-0 >> Connection: Keep-Alive
headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.1 (Java/1.7.0_79)
headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
headers - http-outgoing-0 >> Authorization: Basic dGN1YWRtaW46c3RhcnQ=
wire - http-outgoing-0 >> "DELETE /prod/update-rest/private/deleteGroup/AS123 HTTP/1.1[\r][\n]"
wire - http-outgoing-0 >> "Host: xyz[\r][\n]"
wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.1 (Java/1.7.0_79)[\r][\n]"
wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
wire - http-outgoing-0 >> "Authorization: Basic dGN1YWRtaW46c3RhcnQ=[\r][\n]"
wire - http-outgoing-0 >> "[\r][\n]"
wire - http-outgoing-0 << "HTTP/1.1 204 No Content[\r][\n]"
wire - http-outgoing-0 << "Date: Mon, 05 Oct 2015 13:30:35 GMT[\r][\n]"
wire - http-outgoing-0 << "Server: Apache/2.2.12 (Linux/SUSE)[\r][\n]"
wire - http-outgoing-0 << "Pragma: No-cache[\r][\n]"
wire - http-outgoing-0 << "Cache-Control: no-cache[\r][\n]"
wire - http-outgoing-0 << "Expires: Thu, 01 Jan 1970 01:00:00 CET[\r][\n]"
wire - http-outgoing-0 << "Content-Length: 22[\r][\n]"
wire - http-outgoing-0 << "Keep-Alive: timeout=15, max=99[\r][\n]"
wire - http-outgoing-0 << "Connection: Keep-Alive[\r][\n]"
wire - http-outgoing-0 << "Content-Type: */*[\r][\n]"
wire - http-outgoing-0 << "[\r][\n]"
headers - http-outgoing-0 << HTTP/1.1 204 No Content
headers - http-outgoing-0 << Date: Mon, 05 Oct 2015 13:30:35 GMT
headers - http-outgoing-0 << Server: Apache/2.2.12 (Linux/SUSE)
headers - http-outgoing-0 << Pragma: No-cache
headers - http-outgoing-0 << Cache-Control: no-cache
headers - http-outgoing-0 << Expires: Thu, 01 Jan 1970 01:00:00 CET
headers - http-outgoing-0 << Content-Length: 22
headers - http-outgoing-0 << Keep-Alive: timeout=15, max=99
headers - http-outgoing-0 << Connection: Keep-Alive
headers - http-outgoing-0 << Content-Type: */*
MainClientExec - Connection can be kept alive for 15000 MILLISECONDS
HttpAuthenticator - Authentication succeeded
TargetAuthenticationStrategy - Caching 'basic' auth scheme for https://xyz:443
PoolingHttpClientConnectionManager - Connection [id: 0][route: {s}->https://xyz:443] can be kept alive for 15.0 seconds
PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {s}->https://xyz:443][total kept alive: 1; route allocated: 1 of 20; total allocated: 1 of 20]
RequestAddCookies - CookieSpec selected: default
RequestAuthCache - Auth cache not set in the context
PoolingHttpClientConnectionManager - Connection request: [route: {s}->https://xyz:443][total kept alive: 1; route allocated: 1 of 20; total allocated: 1 of 20]
PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {s}->https://xyz:443][total kept alive: 0; route allocated: 1 of 20; total allocated: 1 of 20]
DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 90000
MainClientExec - Executing request DELETE /prod/update-rest/private/deleteGroup/AS678 HTTP/1.1
MainClientExec - Target auth state: UNCHALLENGED
MainClientExec - Proxy auth state: UNCHALLENGED
headers - http-outgoing-0 >> DELETE /prod/update-rest/private/deleteGroup/AS678 HTTP/1.1
headers - http-outgoing-0 >> Host: xyz
headers - http-outgoing-0 >> Connection: Keep-Alive
headers - http-outgoing-0 >> User-Agent: Apache-HttpClient/4.5.1 (Java/1.7.0_79)
headers - http-outgoing-0 >> Accept-Encoding: gzip,deflate
wire - http-outgoing-0 >> "DELETE /prod/update-rest/private/deleteGroup/AS678 HTTP/1.1[\r][\n]"
wire - http-outgoing-0 >> "Host: xyz[\r][\n]"
wire - http-outgoing-0 >> "Connection: Keep-Alive[\r][\n]"
wire - http-outgoing-0 >> "User-Agent: Apache-HttpClient/4.5.1 (Java/1.7.0_79)[\r][\n]"
wire - http-outgoing-0 >> "Accept-Encoding: gzip,deflate[\r][\n]"
wire - http-outgoing-0 >> "[\r][\n]"
wire - http-outgoing-0 << "Group AS123 not found!"
wire - http-outgoing-0 << "HTTP/1.1 401 Unauthorized[\r][\n]"
wire - http-outgoing-0 << "Date: Mon, 05 Oct 2015 13:30:36 GMT[\r][\n]"
wire - http-outgoing-0 << "Server: Apache/2.2.12 (Linux/SUSE)[\r][\n]"
wire - http-outgoing-0 << "Pragma: No-cache[\r][\n]"
wire - http-outgoing-0 << "Cache-Control: no-cache[\r][\n]"
wire - http-outgoing-0 << "Expires: Thu, 01 Jan 1970 01:00:00 CET[\r][\n]"
wire - http-outgoing-0 << "WWW-Authenticate: Basic realm="ApplicationRealm"[\r][\n]"
wire - http-outgoing-0 << "Content-Length: 958[\r][\n]"
wire - http-outgoing-0 << "Keep-Alive: timeout=15, max=98[\r][\n]"
wire - http-outgoing-0 << "Connection: Keep-Alive[\r][\n]"
wire - http-outgoing-0 << "Content-Type: text/html;charset=utf-8[\r][\n]"
wire - http-outgoing-0 << "[\r][\n]"
DefaultHttpResponseParser - Garbage in response: Group AS123 not found!HTTP/1.1 401 Unauthorized
DefaultHttpResponseParser - Garbage in response: Date: Mon, 05 Oct 2015 13:30:36 GMT
DefaultHttpResponseParser - Garbage in response: Server: Apache/2.2.12 (Linux/SUSE)
DefaultHttpResponseParser - Garbage in response: Pragma: No-cache

共有1个答案

邹玮
2023-03-14

我设法解决了我的问题:

我创建了一个HttpRequestExecutor的子类,它覆盖了canResponseHaveBody方法,如下所示:

protected boolean canResponseHaveBody(final HttpRequest request,
    final HttpResponse response) {

    if ("HEAD".equalsIgnoreCase(request.getRequestLine().getMethod())) {
        return false;
    }
    final int status = response.getStatusLine().getStatusCode();
    return status >= HttpStatus.SC_OK
        // && status != HttpStatus.SC_NO_CONTENT
        && status != HttpStatus.SC_NOT_MODIFIED
        && status != HttpStatus.SC_RESET_CONTENT;
}

使用注册后,我能够通过响应来检索垃圾并使用它。

之后,下一个请求就像魅力一样工作。

 类似资料:
  • 我正试图通过新的Java11HttpClient取消http请求。 这是我的测试代码: 我预计,该请求任务将在 行调用后立即被取消。因此,控制台中最后打印的行应该是 但是,当我运行这段代码时,我看到类似这样的内容: 这意味着,在我取消请求后,请求任务仍在运行…所以,这是取消请求的正确方法吗? UPD 取消请求的正确方法是(正如daniel所建议的,UPD2:在方法调用中避免NPE):

  • 我使用AJAX请求通过POST将数据发送到另一个域。因为我的内容类型不是标准的(它是JSON格式),所以需要一个飞行前请求。(使用请求方法:选项) 如维基百科跨域XHR调用图表中所述 我想知道这是否很费时,因为浏览器将必须到达服务器两次或不?也许这取决于每个浏览器的行为? 通过使用内容类型“纯文本”来避免飞行前请求,我是否获得了一些时间?

  • 我正在创建一个数据下载程序,自从使用httpClient以来,它一直给我带来问题 此代码将所需的所有变量附加到URL: } 每当我调用openSession时,它都会以一种简单的方式打印出标题(这正是我需要它做的)。。。 这打印了一个单行,但当我提出另一个打印长行的请求时,它总是带来这个错误: 这是第二个出现错误的请求: 我在currencyPairsRequest()中是否做错了什么?谢谢你花时

  • 我尽力描述我的处境。我的wicket站点包含list wicket组件,其中每个列表元素都有另一个列表。最低级别列表中的每个元素都有下载某个文件的ajax wicket链接。这一切都很好。我习惯了这种懒散的行为。此行为的方法startDownload在link onClick方法中调用。

  • 由于请求体处理,我看到了一个CPU消耗高于预期的问题。我的简单应用程序是使用VertX-Web构建的。它接受POST请求,断言正文长度与内容长度头匹配。此应用程序正在使用一个驱动程序对2个HTTP操作进行基准测试。第一个发送1K,第二个发送8K。每1000毫秒一次。尸体只是短信。 在基准测试期间,我发现stackdumps显示多个线程在同一个方法中 io.netty.handler.codec.h

  • 更新: 我已经尝试了,正如下面@vonc回答的那样。但这里的问题是,当我使用时,它删除了中的文件夹。然后没有包的api详细信息,所以它不起作用。您知道更好的方法吗?