Dernière modification : 03/02/2021

Spring REST - Lecture du header HTTP

Dans cet article nous allons voir comment lire le contenu de l'entête HTTP avec Spring. Pour cela nous allons utiliser l'annotation @RequestHeader tout au long de cet article.

1. Accès à un seul entête

L'annotation @RequestHeader permet d'accéder aux headers. Si nous souhaitons un entête en particulier, il est nécessaire de renseigner celui-ci directement dans l'annotation. Exemple :

@GetMapping("/headerTest")
public ResponseEntity headerTest(@RequestHeader("accept-language") String language) {
	System.out.println(language); // Output : fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
	return ResponseEntity.ok("");
}

Remarque : Si le nom de l'entête fourni n'existe pas dans le header, alors une erreur 400 est levée.

Il est possible mettre d'autres types à la place de String, notamment dans le cas ou l'attendu serait un entier. Exemple :

@GetMapping("/headerTest")
public ResponseEntity headerTest(@RequestHeader("dnt") Integer dnt) {
	System.out.println(dnt);
	return ResponseEntity.ok("");
}

Remarque : À la place de mettre le nom de l'entête recherché directement dans l'annotation, il est possible d'utiliser les attributs name et value. Le comportement restera le même que précédemment.

2. Lire plusieurs entête

Si l'on souhaite lire plusieurs entête, pour des raisons de lisibilité (en vue de ne pas trop surcharger la méthode), il peut être intéressant de récupérer une map contenant l'enssemble des entête HTTP. Exemple :

@GetMapping("/headerTest")
public ResponseEntity headerTest(@RequestHeader Map headers) {
	headers.forEach((key, value) -> System.out.println(String.format("Header '%s' = %s", key, value)));
	return ResponseEntity.ok("");
}

Remarque : Si plusieurs valeurs sont utilisées pour la même clé, alors utiliser MultiValueMap à la place de Map.

Ou encore directement via l'objet HttpHeaders :

@GetMapping("/headerTest")
public ResponseEntity headerTest(@RequestHeader HttpHeaders httpHeaders) {
	httpHeaders.getAcceptLanguage().forEach(x -> System.out.println(x.getRange()));
	return ResponseEntity.ok("");
}

3. Rendre optionel une option

Comme vu précédemment, dans le cas d'une utilisation de l'annotation @RequestHeader avec l'entête accept-language dans l'annotation, si celle-ci est absente, alors une erreur 400 est levée. Pour contourner ce problème, il est possible de rendre optionel l'entête que l'on souhaite récupérer. Cela est réalisé via l'attribut required = false. Exemple :

@GetMapping("/headerTest")
public ResponseEntity headerTest(@RequestHeader(value = "other-header", required = false) String otherHeader) {
	System.out.println(otherHeader); // null
	return ResponseEntity.ok("");
}

L'attribut defaultValue permet d'attribuer une valeur par défaut si aucun entête ne correspond à celui recherché. Cela permet d'éviter la vérification de la nullité du header. Exemple :

@GetMapping("/headerTest")
public ResponseEntity headerTest(@RequestHeader(value = "other-header", defaultValue = "test") String otherHeader) {
	System.out.println(otherHeader); // test
	return ResponseEntity.ok("");
}