4.1 Il metodo send(), BodyHandlers

Hai finito di imparare come formare una richiesta http , quindi puoi passare alla cosa più importante: inviare questa richiesta. Nel caso più semplice, questo è facile da fare:

HttpRequest request = HttpRequest.newBuilder(new URI("https://codegym.cc")).build();

   HttpClient client = HttpClient.newBuilder()
        .version(Version.HTTP_1_1)
        .build();

   HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
   System.out.println(response.statusCode() );
   System.out.println(response.body() );

E cosa sono BodyHandlersquesti? Cosa ne pensi? Hai inviato una richiesta, il che significa che dovresti ricevere una risposta - http response. E questa risposta può avere response body: una stringa, un file, un array di byte, un InputStream.

Sì, sì, è vero. Proprio come quando si forma una richiesta, è necessario specificare il tipo response bodydi risposta. Ci possono essere 8 pezzi in totale:

  • BodyHandlers.ofByteArray
  • BodyHandlers.ofString
  • BodyHandlers.ofFile
  • BodyHandlers.discarding
  • BodyHandlers.replacing
  • BodyHandlers.ofLines
  • BodyHandlers.fromLineSubscriber

A seconda del tipo che BodyHandlershai passato al metodo send(), restituirà un tale tipo di risultato. Esempio:

// response body is ignored
HttpResponse<Void> response = client.send(request, BodyHandlers.discarding());
// response body is a string
 HttpResponse<String>response = client.send(request, BodyHandlers.ofString());
// response body is a file
HttpResponse<Path> response = client.send(request, BodyHandlers.ofFile(Paths.get("readme.txt")));
// response body is an InputStream
HttpResponse<InputStream> response = client.send(request, BodyHandlers.ofInputStream());

Se un file deve essere inviato come risposta, è BodyHandlers.ofFile()necessario passare il nome del file locale al metodo, dove verrà salvato dall'oggetto HttpClient.

4.2 Metodo followRedirects()

301Inoltre, quando si invia una richiesta, è possibile specificare cosa deve fare HttpClient se il server invia o 302(reindirizzamento temporaneo o permanente) in risposta . Immagina che il server abbia inviato un codice 302e devi: tenere traccia di questa situazione, ottenere un nuovo URL dalla risposta e inviare la richiesta al nuovo indirizzo.

Non mi piacerebbe molto farlo, soprattutto considerando che questa situazione è comune ed è stata a lungo automatizzata in tutti i client http. Anche in questo HttpClient devi solo specificare quale modalità di reindirizzamento scegli quando invii la richiesta.

HttpResponse response = HttpClient.newBuilder()
  .followRedirects( HttpClient.Redirect.ALWAYS )
  .build()
  .send(request, BodyHandlers.ofString());

Ci sono solo 3 opzioni per un reindirizzamento:

  • SEMPRE - sempre;
  • MAI - mai;
  • NORMALE - sempre, tranne HTTPS -> HTTP.

Come puoi vedere, non ci sono molte opzioni qui, ma è sempre meglio avere la possibilità di personalizzare piuttosto che non averla.

4.4 Il metodo proxy()

Ci sono un paio di opzioni più utili, ma non usate spesso. Non ti servono esattamente finché non ne hai bisogno :)

Il primo è proxy. Nella vita ordinaria, non li incontri spesso, ma molte grandi aziende hanno al loro interno un complesso sistema di sicurezza del traffico Internet, e quindi varie impostazioni proxy.

Bene, ovviamente, il tuo software, che funzionerà da qualche parte nelle viscere di una tale società, un giorno incontrerà il fatto che dovrà utilizzare un proxy. Pertanto, è positivo che tale opzione sia presente anche qui.

Impostare un proxy è molto semplice - un esempio:

HttpResponse<String> response = HttpClient.newBuilder()
  .proxy( ProxySelector.getDefault())
  .build()
  .send(request, BodyHandlers.ofString());

Il proxy predefinito è stato scelto qui, ma potresti voler impostare il tuo:

HttpResponse response = HttpClient.newBuilder()
  .proxy(ProxySelector.of(new InetSocketAddress("proxy.microsoft.com", 80)))
  .build()
  .send(request, BodyHandlers.ofString());

Non considereremo esattamente come lavorare con un proxy, poiché questo non è incluso nell'ambito di questo corso.

4.5 autenticatore()

E un altro punto importante. Il protocollo HTTP supporta l'autenticazione. Proprio a livello di protocollo.

Ora questo approccio non è quasi utilizzato, ma circa 20 anni fa era comune. La richiesta Http era simile a questa:

http://username@example.com/

O anche così:

http://username:password@example.com/

Questa non è posta. Questo è esattamente il collegamento. E sì, non lo pensavi. Il login e anche la password potrebbero essere specificati direttamente nella richiesta http. Sì, anche adesso puoi. Ecco perché scrivo che di solito nessuno lo fa adesso. Ma c'è una tale possibilità.

Authenticator auth = new Authenticator() {
    @Override
    protected PasswordAuthentication getPasswordAuthentication() {
    return new PasswordAuthentication(
     "username",
        "password".toCharArray());
    }
};

HttpResponse<String> response = HttpClient.newBuilder()
  .authenticator(auth).build()
  .send(request, BodyHandlers.ofString());

Questo è interessante! Sai perché invece che “password"nel codice si dice "password".toCharArray()?

Perché il secondo parametro del costruttore PasswordAuthentication non è String, ma CharArray.

E perché il secondo parametro non lo è String, eh CharArray?

Perché tutte le password non possono essere memorizzate come una stringa intera per motivi di sicurezza, anche nella tua applicazione . Cioè, la tua applicazione nella sua memoria non dovrebbe memorizzare la password come stringa. In modo che se qualcuno creasse una memoria umida, la password non potrebbe essere estratta da essa ...

Ma allo stesso tempo, la password può essere trasmessa tramite un protocollo HTTP non sicuro in mezzo mondo :) :) :)

BENE. Il mondo non è perfetto.

Puoi leggere di più su questo argomento ai link seguenti:

Autenticazione HTTP

Comprensione dell'autenticazione HTTP