gpt4 book ai didi

java - 数据完成后才返回响应

转载 作者:行者123 更新时间:2023-12-02 01:43:02 29 4
gpt4 key购买 nike

我在使用 Apache HttpClient4 通过 POST 操作读取大型响应流时遇到问题。正在发送响应,但长度未知。当我用curl使用它时,它立即开始被使用,但是HttpClient它会等到收到整个响应后才开始使用。

使用curl, Activity 看起来像这样,并且输出几乎立即开始写入:

$ curl -v -X POST --data-binary @input.gz http://chemservices:8080/chem-services-cdk-basic/rest/v1/converters/dataset_to_sdf  -H 'Content-Type: application/x-squonk-dataset-molecule+json' -H 'Content-Encoding: gzip' -H 'Accept: chemical/x-mdl-sdfile' -o output.sdf -v
Note: Unnecessary use of -X or --request, POST is already inferred.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0* Trying 172.18.0.6...
* TCP_NODELAY set
* Connected to chemservices (172.18.0.6) port 8080 (#0)
> POST /chem-services-cdk-basic/rest/v1/converters/dataset_to_sdf HTTP/1.1
> Host: chemservices:8080
> User-Agent: curl/7.58.0
> Content-Type: application/x-squonk-dataset-molecule+json
> Content-Encoding: gzip
> Accept: chemical/x-mdl-sdfile
> Content-Length: 19397182
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
} [16384 bytes data]
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH
< Access-Control-Max-Age: 3600
< Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers
< Content-Type: chemical/x-mdl-sdfile
< Transfer-Encoding: chunked
< Date: Sun, 13 Jan 2019 12:30:18 GMT
<
{ [1031 bytes data]
100 172M 0 154M 100 18.4M 7103k 851k 0:00:22 0:00:22 --:--:-- 7301k
* Connection #0 to host chemservices left intact

但是当我使用 HttpClient 时,execute() 操作会阻塞,直到写入整个响应:

LOG.info("Posting commencing");
CloseableHttpResponse resp = httpclient.execute(httpPost);
LOG.info("Posting complete");

正在设置 Content-TypeContent-EncodingAcceptAccept-Encoding header 请求。

如果我将 SocketTimeout 参数设置为足够大的值,我可以获得响应,但显然这不是正确的解决方案!

关于如何正确处理这个问题有什么建议吗?

最佳答案

我相信您需要使用HttpAsyncClient实现异步请求处理。

考虑以下示例,它将以 block 的形式传输响应,您可以在重写的 onCharReceived 方法中处理这些 block 。出于本示例的目的,我只是让它打印每个 block 的长度。

显然,您需要根据需要修改端点、 header 和请求数据:

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncMethods;
import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
import org.apache.http.protocol.HttpContext;

import java.nio.CharBuffer;
import java.util.concurrent.CountDownLatch;

public class HttpAsyncTest {

public static void main(String[] args) {
try (CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault()) {
httpclient.start();

final CountDownLatch latch = new CountDownLatch(1);
final HttpPost request = new HttpPost("https://postman-echo.com/post");
request.setEntity(new StringEntity("This is the request data"));
request.setHeader("Content-Type", "application/x-www-form-urlencoded");

HttpAsyncRequestProducer producer = HttpAsyncMethods.create(request);
AsyncCharConsumer<HttpResponse> consumer = new AsyncCharConsumer<HttpResponse>() {
HttpResponse response;

@Override
protected void onResponseReceived(final HttpResponse response) {
this.response = response;
}

@Override
protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) {
System.out.printf("onCharReceived: %d\n", buf.length());
}

@Override
protected HttpResponse buildResult(final HttpContext context) {
return this.response;
}
};

httpclient.execute(producer, consumer, new FutureCallback<HttpResponse>() {
public void completed(final HttpResponse response3) {
latch.countDown();
System.out.println(request.getRequestLine() + "->" + response3.getStatusLine());
}

public void failed(final Exception ex) {
latch.countDown();
System.out.println(request.getRequestLine() + "->" + ex);
}

public void cancelled() {
latch.countDown();
System.out.println(request.getRequestLine() + " cancelled");
}
});

latch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
}

关于java - 数据完成后才返回响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54168960/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com