Jersey client async POST request to not wait for response
Asked Answered
C

2

6

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");
}
Conover answered 27/4, 2015 at 22:18 Comment(2)
Can you use javax.ws.rs.client instead? I believe Invocation.Builder.async() would do what you want: docs.oracle.com/javaee/7/api/javax/ws/rs/client/…Sparkle
Yes I think I can use javax.ws.rs.client but since I already have the Jersey client running I thought it would be easier to just use the async methods there instead of changing the whole class.Conover
P
2

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();
                }
             }
         });
Photoengrave answered 23/2, 2017 at 13:53 Comment(0)
I
0

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

Ingeringersoll answered 15/10, 2019 at 15:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.