Jersey client async POST request to not wait for response

断了今生、忘了曾经 提交于 2019-12-07 10:39:13

问题


I have created a simple Jersey client and it is able to successfully do a POST request with a payload. But right now it waits for a response from the http endpoint:

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();
}

Ques: Is it possible for the code to not wait for the response.

I was trying to read the Jersey client docs to find if its possible for my code to not wait for the response? I saw that we can only close the connection once we read the response but its not useful in my case. I want to close the connection as soon as I post the payload to the endpoint.

I just need to fire and forget the POST request as I don't care about the response. This is because the processing takes a lot of time at that endpoint and I don't want the thread to wait for the processing.

Also is it possible to wait for the response for some of the requests but not for all? Is there a parameter that I can set in the client that makes it wait/not wait? I am still reading the java docs so this might be a very simple setting but I wasn't able to find till now so asking here. Thanks!

[Update]

I got it working with the following code but when I run my java example code it prints start & done immediately but the program keeps running for a while and then exits. I am guessing its waiting for the Future response so is it possible that I can make my script not wait for it? The code is:

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");
}

回答1:


I used a TypeListener to make it really asynchronous. The onComplete method would be called when the response is received.

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:


My response is a bit late, but I seem to have solution to both your problems. Hopefully it may help someone in future.

I am keeping it short and giving references of questions already asked on this platform

For first problem, where you do not want to wait. You may use a timeout property provided by jersey in its client object. Below is a link which addresses this problem. How to set the connection and read timeout with Jersey 2.x?

For the second problem where you can see that it stops only after running for sometime is because the client thread keeps running until it times out. Please find a link below with better description JerseyClient async calls seems to leave hanging threads



来源:https://stackoverflow.com/questions/29906956/jersey-client-async-post-request-to-not-wait-for-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!