package com.packt.learnjava.ch11_network; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodyHandlers; import java.net.http.HttpResponse.PushPromiseHandler; import java.net.http.WebSocket; import java.net.http.WebSocket.Listener; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionStage; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.function.Function; public class HttpClientDemo { public static void main(String[] args) { /* Run UrlServer before uncommenting and running * any of the following examples */ //get(); //post(); //getAsync(); //postAsync(); //postAsyncMultiple(); //postAsyncMultipleUsingPool(); //push(); webSocket(); } private static void get(){ HttpClient httpClient = HttpClient.newHttpClient(); /* HttpClient httpClient = HttpClient.newBuilder() .version(HttpClient.Version.HTTP_2) // default .build(); */ HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("http://localhost:3333/something")) .GET() // default .build(); try { HttpResponse<String> resp = httpClient.send(req, BodyHandlers.ofString()); System.out.println("Response: " + resp.statusCode() + " : " + resp.body()); } catch (Exception ex) { ex.printStackTrace(); } } private static void post(){ HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("http://localhost:3333/something")) .POST(BodyPublishers.ofString("Hi there!")) .build(); try { HttpResponse<String> resp = httpClient.send(req, BodyHandlers.ofString()); System.out.println("Response: " + resp.statusCode() + " : " + resp.body()); } catch (Exception ex) { ex.printStackTrace(); } } private static void getAsync(){ HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("http://localhost:3333/something")) .GET() // default .build(); /* CompletableFuture<Void> cf = httpClient.sendAsync(req, BodyHandlers.ofString()) .thenAccept(resp -> System.out.println("Response: " + resp.statusCode() + " : " + resp.body())); */ CompletableFuture<String> cf = httpClient.sendAsync(req, BodyHandlers.ofString()) .thenApply(resp -> "Server responded: " + resp.body()); System.out.println("The request was sent asynchronously..."); try { System.out.println("CompletableFuture get: " + cf.get(5, TimeUnit.SECONDS)); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Exit the client..."); } private static void postAsync(){ HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("http://localhost:3333/something")) .POST(BodyPublishers.ofString("Hi there!")) .build(); CompletableFuture<String> cf = httpClient.sendAsync(req, BodyHandlers.ofString()) .thenApply(resp -> "Server responded: " + resp.body()); System.out.println("The request was sent asynchronously..."); try { System.out.println("CompletableFuture get: " + cf.get(5, TimeUnit.SECONDS)); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Exit the client..."); } private static void postAsyncMultiple(){ HttpClient httpClient = HttpClient.newHttpClient(); List<CompletableFuture<String>> cfs = new ArrayList<>(); List<String> nums = List.of("1", "2", "3"); for(String num: nums){ HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("http://localhost:3333/something")) .POST(BodyPublishers.ofString("Hi! My name is " + num + ".")) .build(); CompletableFuture<String> cf = httpClient .sendAsync(req, BodyHandlers.ofString()) .thenApply(rsp -> "Server responded to msg " + num + ": " + rsp.statusCode() + " : " + rsp.body()); cfs.add(cf); } System.out.println("The requests were sent asynchronously..."); try { for(CompletableFuture<String> cf: cfs){ System.out.println("CompletableFuture get: " + cf.get(5, TimeUnit.SECONDS)); } } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Exit the client..."); } private static void postAsyncMultipleUsingPool(){ ExecutorService pool = Executors.newFixedThreadPool(2); HttpClient httpClient = HttpClient.newBuilder().executor(pool).build(); List<CompletableFuture<String>> cfs = new ArrayList<>(); List<String> nums = List.of("1", "2", "3"); for(String num: nums){ HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("http://localhost:3333/something")) .POST(BodyPublishers.ofString("Hi! My name is " + num + ".")) .build(); CompletableFuture<String> cf = httpClient .sendAsync(req, BodyHandlers.ofString()) .thenApply(rsp -> "Server responded to msg " + num + ": " + rsp.statusCode() + " : " + rsp.body()); cfs.add(cf); } System.out.println("The requests were sent asynchronously..."); try { for(CompletableFuture<String> cf: cfs){ System.out.println("CompletableFuture get: " + cf.get(5, TimeUnit.SECONDS)); } } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Exit the client..."); } private static void push(){ HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest req = HttpRequest.newBuilder() .uri(URI.create("http://localhost:3333/something")) .GET() .build(); CompletableFuture cf = httpClient.sendAsync(req, BodyHandlers.ofString(), (PushPromiseHandler) HttpClientDemo::applyPushPromise); System.out.println("The request was sent asynchronously..."); try { System.out.println("CompletableFuture get: " + cf.get(5, TimeUnit.SECONDS)); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Exit the client..."); } private static void applyPushPromise(HttpRequest initReq, HttpRequest pushReq, Function<BodyHandler, CompletableFuture<HttpResponse>> acceptor) { CompletableFuture<Void> cf = acceptor.apply(BodyHandlers.ofString()) .thenAccept(resp -> System.out.println("Got pushed response " + resp.uri())); try { System.out.println("Pushed completableFuture get: " + cf.get(1, TimeUnit.SECONDS)); } catch (Exception ex) { ex.printStackTrace(); } System.out.println("Exit the applyPushPromise function..."); } private static void webSocket(){ HttpClient httpClient = HttpClient.newHttpClient(); WebSocket webSocket = httpClient.newWebSocketBuilder() .buildAsync(URI.create("ws://echo.websocket.org"), new WsClient()) .join(); System.out.println("The WebSocket was created and ran asynchronously."); try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException ex) { ex.printStackTrace(); } webSocket.sendClose(WebSocket.NORMAL_CLOSURE, "Normal closure") .thenRun(() -> System.out.println("Close is sent.")); } private static class WsClient implements WebSocket.Listener { @Override public void onOpen(WebSocket webSocket) { System.out.println("Connection established."); webSocket.sendText("Some message", true); Listener.super.onOpen(webSocket); } @Override public CompletionStage onText(WebSocket webSocket, CharSequence data, boolean last) { System.out.println("Method onText() got data: " + data); if(!webSocket.isOutputClosed()) { webSocket.sendText("Another message", true); } return Listener.super.onText(webSocket, data, last); } @Override public CompletionStage onClose(WebSocket webSocket, int statusCode, String reason) { System.out.println("Closed with status " + statusCode + ", reason: " + reason); return Listener.super.onClose(webSocket, statusCode, reason); } } }