Execute HTTP POST asynchronously JAVA

2

I have a method that sends a POST to the server, how can I send multiple requests asynchronously?

public void sendPost (Object content) {     
    ObjectMapper mapper = new ObjectMapper();
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    URL url;

    try {

        String jsonInString = mapper.writeValueAsString(content);

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

            HttpPost post = new HttpPost(URL_POST);
            StringEntity params = new StringEntity(jsonInString, "UTF-8");
            post.addHeader("content-type", "application/json");
            post.setEntity(params);
            CloseableHttpResponse response = httpClient.execute(post);
            String responseBody = EntityUtils.toString(response.getEntity());
     }
}
    
asked by anonymous 04.01.2018 / 12:08

2 answers

2

Here is an example that might help you:

public class PostRequest implements Callable<InputStream> {

    private String url;
    private String body;

    public PostRequest(String url, String body) {
        this.url = url;
        this.body = body;
    }

    @Override
    public InputStream call() throws Exception {

        URL myurl = new URL(url);
        HttpURLConnection con = (HttpURLConnection) myurl.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", "Java client");
        con.setDoOutput(true);

        try( DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
           wr.writeBytes(body);
        }

        return con.getInputStream();
    }
}

public class Main {

    public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        Future<InputStream> response1 = executor.submit(new PostRequest(**<url>**, **<content>**));
        Future<InputStream> response2 = executor.submit(new PostRequest(**<url>**, **<content>**));

        ByteArrayOutputStream totalResponse = new ByteArrayOutputStream();

        IOUtils.copy(response1.get(), totalResponse);
        response1.get().close();
        IOUtils.copy(response2.get(), totalResponse);
        response2.get().close();

        executor.shutdown();

        System.out.println(totalResponse.toString());
    }
}
    
04.01.2018 / 13:52
0

It looks like you're using Apache Http Components , and api already has the module HttpAsyncClient for asynchronous requests.

pom.xml

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpasyncclient</artifactId>
    <version>4.1.3</version>
</dependency>

Following more or less the same line of your implementation:

public class HttpUtils {

    private static final ObjectMapper MAPPER = new ObjectMapper();      
    private static final CloseableHttpAsyncClient HTTP_CLIENT = HttpAsyncClients.createDefault();

    static {
        HTTP_CLIENT.start();
    }

    public static void post(String url, Object body, FutureCallback<HttpResponse> callback) throws IOException {        
        StringEntity json = new StringEntity(MAPPER.writeValueAsString(body), "UTF-8");

        HttpPost post = new HttpPost(url);
        post.setEntity(json);

        HTTP_CLIENT.execute(post, callback);        
    }

    public static void shutdown() throws IOException {
        HTTP_CLIENT.close();
    }

}

Testing with JsonPlaceHolder :

public static void main(String[] args) throws IOException, InterruptedException {

    BlogPost post = new BlogPost();
    post.setId(1);
    post.setUserId(1);
    post.setTitle("Async Request");
    post.setBody("This is an async post request");

    FutureCallback<HttpResponse> callback = new FutureCallback<HttpResponse>() {

        @Override
        public void failed(Exception e) {
            e.printStackTrace(System.out);                      
        }

        @Override
        public void completed(HttpResponse response) {
            try {
                System.out.println(EntityUtils.toString(response.getEntity()));
            } catch (ParseException | IOException e) {
                e.printStackTrace();
            }

        }

        @Override
        public void cancelled() {
            System.out.println("cancelled");                        
        }
    };

    HttpUtils.post("https://jsonplaceholder.typicode.com/posts", post, callback);

    Thread.sleep(5000); // (teste) - aguarda resposta antes de finalizar
    HttpUtils.shutdown();

}
    
04.01.2018 / 16:43