Jersey客户端异步POST请求不等待响应

6
我已经创建了一个简单的Jersey客户端,并成功地使用有效负载执行了POST请求。但现在它正在等待来自http端点的响应:
public void callEndpoint(String endpoint, String payload) {

    try {
        ClientConfig config = new DefaultClientConfig();
        Client client = Client.create(config);
        WebResource webResource = client.resource(getBaseURI(endpoint));

        log.debug("Sending payload [" + payload + "] to URL - [" + getBaseURI(endpoint) + "]");

        // POST method - Is this blocking?
        // Is it possible to not wait for response here
        ClientResponse response = webResource.accept("application/json")
                                             .type("application/json")
                                             .post(ClientResponse.class, payload);
        if (response.getStatus() != 200) {
            log.error("The endpoint [" + getBaseURI(endpoint) + "] returned a non 200 status code [" + response.getStatus() + "] ");
        }

    } catch (Exception e) {
        log.error("The endpoint for " + endpoint + " - " + getBaseURI(endpoint) + " is not reachable. This is the exception - " + e);
    }

}

private URI getBaseURI(String endpoint) {
    // Get this URI from config
    String URL = "http://www.somewhere.com/v2/" + endpoint;
    return UriBuilder.fromUri(URL).build();
}

问题:代码是否可以不等待响应?

我正在阅读Jersey客户端文档,想知道我的代码是否有可能不等待响应?我看到我们只能在读取响应后关闭连接,但这对我的情况没有用。我想在将有效载荷发送到终端点后立即关闭连接。

我只需要启动并忘记POST请求,因为我不关心响应。这是因为处理在该终点需要很长时间,而我不希望线程等待处理。

另外,是否可能等待某些请求的响应,但不是所有请求?在客户端中是否可以设置参数以使其等待/不等待?我仍在阅读Java文档,所以这可能是一个非常简单的设置,但我现在还没有找到,所以在这里问一下。谢谢!

[更新]

我使用以下代码使其工作,但当我运行示例Java代码时,它立即打印开始和结束,但程序仍然运行一段时间,然后退出。我猜它正在等待Future响应,所以是否可能使我的脚本不等待它? 代码如下:

public static void callEndpoint(String endpoint, String payload) {

    try {
        ClientConfig config = new DefaultClientConfig();
        Client client = Client.create(config);
        AsyncWebResource webResource = client.asyncResource(getBaseURI(endpoint));

        // POST method
        System.out.println("start");
        Future<ClientResponse> resp = webResource.accept("application/json")
                .type("application/json")
                .post(ClientResponse.class, payload);
        // This line makes the code wait for output
        //System.out.println(resp.get()); 

    } catch (Exception e) {

        System.out.println ("The endpoint for " + endpoint + " - " + getBaseURI(endpoint) + " is not reachable. This is the exception - " + e);
    }
    System.out.println("done");
}

你可以使用javax.ws.rs.client吗?我相信Invocation.Builder.async()会做你想要的事情:http://docs.oracle.com/javaee/7/api/javax/ws/rs/client/Invocation.Builder.html#async%28%29 - Brett Kail
是的,我认为我可以使用javax.ws.rs.client,但由于我已经在运行Jersey客户端,所以我想直接使用那里的异步方法会更容易,而不是更改整个类。 - Sumitk
2个回答

2
我使用了TypeListener使其真正异步化。当接收到响应时,将调用onComplete方法。
webResource.post(new TypeListener<ClientResponse>(ClientResponse.class) {
             @Override
             public void onComplete(Future<ClientResponse> f) throws InterruptedException {
                 try {
                    ClientResponse response = f.get();
                    if (response == null || response.getClientResponseStatus() != Status.OK) {
                        System.err.println(" Async " + response.getClientResponseStatus()+" "+response.getStatus());
                    } else{
                        System.out.println(" Async " + response.getClientResponseStatus()+" "+response.getStatus()+" "+response.getEntity(String.class));
                    }
                } catch (ExecutionException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
         });

0

我回复有点晚了,但我似乎对你的两个问题都有解决方案。希望它能帮到未来的某个人。

我会简短地给出已经在这个平台上提出的问题的参考。

对于第一个问题,当你不想等待时,你可以使用Jersey提供的客户端对象的超时属性。下面是一个解决这个问题的链接。 如何使用Jersey 2.x设置连接和读取超时?

对于第二个问题,你可以看到它只在运行一段时间后停止,这是因为客户端线程会一直运行直到超时。请参考下面的链接以获得更详细的描述。 JerseyClient异步调用似乎会留下悬挂的线程


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接