Comment lire les en-têtes HTTP dans les contrôleurs Spring REST

1. Introduction

Dans ce tutoriel rapide, nous allons voir comment accéder aux en-têtes HTTP dans un contrôleur Spring Rest.

Tout d'abord, nous utiliserons l' annotation @RequestHeader pour lire les en-têtes individuellement ainsi que tous ensemble.

Après cela, nous examinerons plus en détail les attributs de @RequestHeader .

2. Accès aux en-têtes HTTP

2.1. Individuellement

Si nous avons besoin d'accéder à un en-tête spécifique, nous pouvons configurer @RequestHeader avec le nom de l'en-tête:

@GetMapping("/greeting") public ResponseEntity greeting(@RequestHeader("accept-language") String language) { // code that uses the language variable return new ResponseEntity(greeting, HttpStatus.OK); }

Ensuite, nous pouvons accéder à la valeur en utilisant la variable passée dans notre méthode. Si un en-tête nommé accept-language n'est pas trouvé dans la requête, la méthode renvoie une erreur «400 Bad Request».

Nos en-têtes ne doivent pas nécessairement être des chaînes. Par exemple, si nous savons que notre en-tête est un nombre, nous pouvons déclarer notre variable comme un type numérique:

@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. Tout à la fois

Si nous ne savons pas quels en-têtes seront présents, ou si nous en avons besoin de plus que ce que nous voulons dans la signature de notre méthode, nous pouvons utiliser l' annotation @RequestHeader sans nom spécifique.

Nous avons quelques choix pour notre type de variable: un objet Map , un MultiValueMap ou un objet HttpHeaders .

Tout d'abord, obtenons les en-têtes de requête sous forme de carte :

@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); }

Si nous utilisons une carte et que l'un des en-têtes a plus d'une valeur , nous n'obtiendrons que la première valeur . C'est l'équivalent de l'utilisation de la méthode getFirst sur un MultiValueMap .

Si nos en-têtes peuvent avoir plusieurs valeurs, nous pouvons les obtenir sous forme de 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); }

Nous pouvons également obtenir nos en-têtes en tant qu'objet 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' objet HttpHeaders a des accesseurs pour les en-têtes d'application courants.

Lorsque nous accédons à un en-tête par nom à partir d'un objet Map , MultiValueMap ou HttpHeaders , nous obtiendrons un null s'il n'est pas présent.

3. Attributs @RequestHeader

Maintenant que nous avons passé en revue les bases de l'accès aux en-têtes de requête avec l' annotation @RequestHeader , examinons de plus près ses attributs.

Nous avons déjà utilisé les attributs de nom ou de valeur implicitement lorsque nous avons spécifiquement nommé notre en-tête:

public ResponseEntity greeting(@RequestHeader("accept-language") String language) {}

Nous pouvons accomplir la même chose en utilisant l' attribut name :

public ResponseEntity greeting( @RequestHeader(name = "accept-language") String language) {}

Ensuite, utilisons l' attribut value exactement de la même manière:

public ResponseEntity greeting( @RequestHeader(value = "accept-language") String language) {}

Lorsque nous nommons un en-tête spécifiquement, l'en-tête est requis par défaut. Si l'en-tête n'est pas trouvé dans la requête, le contrôleur renvoie une erreur 400.

Utilisons l' attribut required pour indiquer que notre en-tête n'est pas requis:

@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); }

Puisque notre variable sera nulle si l'en-tête n'est pas présent dans la requête , nous devons nous assurer de faire la vérification de null appropriée .

Utilisons l' attribut defaultValue pour fournir une valeur par défaut pour notre en-tête:

@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. Conclusion

Dans ce court didacticiel, nous avons appris à accéder aux en-têtes de requête dans les contrôleurs Spring REST. Tout d'abord, nous avons utilisé l' annotation @RequestHeader pour fournir des en-têtes de requête à nos méthodes de contrôleur.

Après un aperçu des bases, nous avons examiné en détail les attributs de l' annotation @RequestHeader .

L'exemple de code est disponible à l'adresse over sur GitHub.