1. Introduzione
In questo breve tutorial, vedremo come accedere alle intestazioni HTTP in un controller Spring Rest.
Innanzitutto, utilizzeremo l' annotazione @RequestHeader per leggere le intestazioni individualmente e tutte insieme.
Dopodiché, daremo uno sguardo più approfondito agli attributi di @RequestHeader .
2. Accesso alle intestazioni HTTP
2.1. Individualmente
Se abbiamo bisogno di accedere a un'intestazione specifica, possiamo configurare @RequestHeader con il nome dell'intestazione:
@GetMapping("/greeting") public ResponseEntity greeting(@RequestHeader("accept-language") String language) { // code that uses the language variable return new ResponseEntity(greeting, HttpStatus.OK); }
Quindi, possiamo accedere al valore utilizzando la variabile passata nel nostro metodo. Se un'intestazione denominata accept-language non viene trovata nella richiesta, il metodo restituisce un errore "400 Bad Request".
Le nostre intestazioni non devono essere stringhe. Ad esempio, se sappiamo che la nostra intestazione è un numero, possiamo dichiarare la nostra variabile come un tipo numerico:
@GetMapping("/double") public ResponseEntity doubleNumber(@RequestHeader("my-number") int myNumber) { return new ResponseEntity(String.format("%d * 2 = %d", myNumber, (myNumber * 2)), HttpStatus.OK); }
2.2. Tutto in una volta
Se non siamo sicuri di quali intestazioni saranno presenti, o se ne occorrono più di quante ne vogliamo nella firma del nostro metodo, possiamo usare l' annotazione @RequestHeader senza un nome specifico.
Abbiamo alcune scelte per il nostro tipo di variabile: un oggetto Map , MultiValueMap o HttpHeaders .
Per prima cosa, otteniamo le intestazioni della richiesta come mappa :
@GetMapping("/listHeaders") public ResponseEntity listAllHeaders( @RequestHeader Map headers) { headers.forEach((key, value) -> { LOG.info(String.format("Header '%s' = %s", key, value)); }); return new ResponseEntity( String.format("Listed %d headers", headers.size()), HttpStatus.OK); }
Se usiamo una mappa e una delle intestazioni ha più di un valore , otterremo solo il primo valore . Questo è l'equivalente dell'utilizzo del metodo getFirst su MultiValueMap .
Se le nostre intestazioni possono avere più valori, possiamo ottenerle come MultiValueMap :
@GetMapping("/multiValue") public ResponseEntity multiValue( @RequestHeader MultiValueMap headers) { headers.forEach((key, value) -> LOG.info(String.format( "Header '%s' = %s", key, value.stream().collect(Collectors.joining("); return new ResponseEntity( String.format("Listed %d headers", headers.size()), HttpStatus.OK); }
Possiamo anche ottenere le nostre intestazioni come oggetto HttpHeaders :
@GetMapping("/getBaseUrl") public ResponseEntity getBaseUrl(@RequestHeader HttpHeaders headers) { InetSocketAddress host = headers.getHost(); String url = "//" + host.getHostName() + ":" + host.getPort(); return new ResponseEntity(String.format("Base URL = %s", url), HttpStatus.OK); }
L' oggetto HttpHeaders dispone di funzioni di accesso per le intestazioni delle applicazioni comuni.
Quando accediamo a un'intestazione in base al nome da una mappa , MultiValueMap o l' oggetto HttpHeaders , otterremo un valore nullo se non è presente.
3. Attributi @RequestHeader
Ora che abbiamo esaminato le basi dell'accesso alle intestazioni delle richieste con l' annotazione @RequestHeader , diamo un'occhiata più da vicino ai suoi attributi.
Abbiamo già utilizzato implicitamente gli attributi name o value quando abbiamo specificamente chiamato la nostra intestazione:
public ResponseEntity greeting(@RequestHeader("accept-language") String language) {}
Possiamo ottenere la stessa cosa utilizzando l' attributo name :
public ResponseEntity greeting( @RequestHeader(name = "accept-language") String language) {}
Successivamente, usiamo l' attributo value esattamente allo stesso modo:
public ResponseEntity greeting( @RequestHeader(value = "accept-language") String language) {}
Quando nominiamo un'intestazione in modo specifico, l'intestazione è richiesta per impostazione predefinita. Se l'intestazione non viene trovata nella richiesta, il controller restituisce un errore 400.
Usiamo l' attributo richiesto per indicare che la nostra intestazione non è richiesta:
@GetMapping("/nonRequiredHeader") public ResponseEntity evaluateNonRequiredHeader( @RequestHeader(value = "optional-header", required = false) String optionalHeader) { return new ResponseEntity(String.format( "Was the optional header present? %s!", (optionalHeader == null ? "No" : "Yes")),HttpStatus.OK); }
Poiché la nostra variabile sarà nulla se l'intestazione non è presente nella richiesta , dobbiamo essere sicuri di eseguire il controllo null appropriato .
Usiamo l' attributo defaultValue per fornire un valore predefinito per la nostra intestazione:
@GetMapping("/default") public ResponseEntity evaluateDefaultHeaderValue( @RequestHeader(value = "optional-header", defaultValue = "3600") int optionalHeader) { return new ResponseEntity( String.format("Optional Header is %d", optionalHeader), HttpStatus.OK); }
4. Conclusione
In questo breve tutorial, abbiamo imparato come accedere alle intestazioni delle richieste nei controller Spring REST. Innanzitutto, abbiamo utilizzato l' annotazione @RequestHeader per fornire le intestazioni delle richieste ai nostri metodi di controller.
Dopo aver esaminato le basi, abbiamo esaminato in dettaglio gli attributi per l' annotazione @RequestHeader .
Il codice di esempio è disponibile su GitHub.