5.1 método sendAsync()

También puede enviar solicitudes asincrónicas mediante HttpClient. Por lo general, esto se hace en tres casos.

El primer caso es que la solicitud llevará mucho tiempo , por ejemplo, enviar/recibir un archivo. A continuación, esta operación se inicia y ejecuta de forma asíncrona.

El segundo caso es que necesita enviar solicitudes con mucha frecuencia y no desea esperar una respuesta de la solicitud anterior antes de enviar la siguiente.

Y finalmente, el tercer caso: el resultado de su solicitud no es importante para usted . Por ejemplo, toma una captura de pantalla de su pantalla una vez por minuto y la envía al servidor. Es decir, la lógica de su aplicación asume que hay muchas solicitudes y no todas llegan. Entonces es conveniente trabajar de acuerdo con el principio: enviar y olvidar.

Para enviar una solicitud asíncrona, debe llamar a un método sendAsync()en un objeto de la clase HttpClient. Este método sale inmediatamente y devuelve un CompletableFuture<HttpResponse>. Con él, puede rastrear cuándo se ejecuta realmente la solicitud, así como ejecutar cierto código después de que se complete la solicitud. Ejemplo:

HttpClient client = HttpClient.newBuilder().build();

CompletableFuture<HttpResponse<String>> response = client.sendAsync(
        request,
        HttpResponse.BodyHandlers.ofString()
);

El método sendAsync()devuelve un objeto CompletableFutureque contiene un HttpResponse dentro, que contiene la cadena que devolverá el servidor.

5.2 El método executor(), ExecutorService

Además, HttpClient le permite pasar a él ExecutorService(un conjunto de subprocesos) que se utilizará para realizar solicitudes asincrónicas. En realidad, en las aplicaciones Java del lado del servidor, esto siempre se hace.

Después de todo, si por cada solicitud entrante a su API, lanzará varias solicitudes asincrónicas en otro lugar, no tendrá suficientes hilos. Ejemplo:

ExecutorService executorService = Executors.newFixedThreadPool(2);

CompletableFuture<HttpResponse<String>> response1 = HttpClient.newBuilder()
  .executor(executorService)
  .build()
  .sendAsync(request, HttpResponse.BodyHandlers.ofString());

CompletableFuture<HttpResponse<String>> response2 = HttpClient.newBuilder()
  .executor(executorService)
  .build()
  .sendAsync(request, HttpResponse.BodyHandlers.ofString());

Si el grupo de subprocesos no está configurado, el valor predeterminado es .java.util.concurrent.Executors.newCachedThreadPool()