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

Posted

技术标签:

【中文标题】泽西客户端异步 POST 请求不等待响应【英文标题】:Jersey client async POST request to not wait for response 【发布时间】:2015-07-06 13:38:03 【问题描述】:

我创建了一个简单的 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 client docs 以查找我的代码是否有可能不等待响应?我看到我们只能在阅读响应后关闭连接,但在我的情况下它没有用。我想在将有效负载发布到端点后立即关闭连接。

我只需要触发并忘记 POST 请求,因为我不关心响应。这是因为该端点的处理需要大量时间,我不希望线程等待处理。

是否也可以等待某些请求的响应,但不能等待所有请求的响应?我可以在客户端中设置一个参数来让它等待/不等待吗?我仍在阅读 java 文档,所以这可能是一个非常简单的设置,但直到现在我都无法找到,所以在这里询问。谢谢!

[更新]

我使用以下代码让它工作,但是当我运行我的 java 示例代码时,它会立即打印 start & done 但程序会继续运行一段时间然后退出。我猜它正在等待未来的响应,所以我可以让我的脚本不等待它吗?代码是:

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() 会做你想做的事:docs.oracle.com/javaee/7/api/javax/ws/rs/client/… 是的,我想我可以使用 javax.ws.rs.client 但由于我已经运行了 Jersey 客户端,我认为只使用那里的异步方法而不是更改整个类会更容易。 【参考方案1】:

我使用 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();
                
             
         );

【讨论】:

【参考方案2】:

我的回复有点晚了,但我似乎对你的两个问题都有解决方案。希望它可以在将来对某人有所帮助。

我会保持简短,并提供此平台上已经提出的问题的参考

对于第一个问题,您不想等待。您可以在其客户端对象中使用 jersey 提供的超时属性。以下是解决此问题的链接。 How to set the connection and read timeout with Jersey 2.x?

对于第二个问题,您可以看到它仅在运行一段时间后才停止,这是因为客户端线程一直运行直到超时。请在下面找到更好描述的链接 JerseyClient async calls seems to leave hanging threads

【讨论】:

以上是关于泽西客户端异步 POST 请求不等待响应的主要内容,如果未能解决你的问题,请参考以下文章

客户端响应过滤器读取实体问题(泽西)

AsyncResponse ConnectionCallback 不会在泽西岛触发

Django - 组件

AJAX异步请求

Ajax

Django( Ajax )