Comment accéder aux informations d'en-tête HTTP dans le contrôleur REST Spring MVC?

154

Je suis nouveau dans la programmation Web en général, en particulier en Java, alors je viens d'apprendre ce qu'est un en-tête et un corps.

J'écris des services RESTful en utilisant Spring MVC. Je suis capable de créer des services simples avec le @RequestMappingdans mes contrôleurs. J'ai besoin d'aide pour comprendre comment obtenir des informations d'en-tête HTTP à partir d'une requête qui arrive à ma méthode dans mon contrôleur de service REST. Je voudrais analyser l'en-tête et en tirer des attributs.

Pouvez-vous expliquer comment je procède pour obtenir ces informations?

Voix de cheval
la source

Réponses:

264

Lorsque vous annotez un paramètre avec @RequestHeader, le paramètre récupère les informations d'en-tête. Vous pouvez donc faire quelque chose comme ceci:

@RequestHeader("Accept")

pour obtenir l'en- Accepttête.

Donc à partir de la documentation :

@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,
                              @RequestHeader("Keep-Alive") long keepAlive)  {

}

Les valeurs d'en-tête Accept-Encodinget Keep-Alivesont fournies respectivement dans les paramètres encodinget keepAlive.

Et pas de soucis. Nous sommes tous des noobs avec quelque chose.

Vidya
la source
Je vous remercie. Dans Quelques exemples de code dans l'entreprise pour laquelle je travaille, je vois HttpServletRequest comme paramètre et il y a une méthode getHeader dessus. Quelle approche est préférable?
Horse Voice
1
Préférez les abstractions aux détails de bas niveau d'une API. Je préférerais de loin que Spring MVC abrégé les détails de l' ServletAPI. Je peux utiliser les annotations pour extraire ce dont j'ai besoin de la demande.
Vidya
6
Il faut mentionner que vous obtiendrez une erreur de demande incorrecte 400 en réponse au cas où la demande ne contiendrait pas un tel en-tête. Un moyen plus flexible est l'accès direct aux en-têtes de demande comme décrit dans: stackoverflow.com/a/28209710/1828296
lospejos
Je suppose que cela dépend de ce que vous voulez faire, mais une réponse 400 est le comportement que je voudrais presque toujours dans ce cas.
Vidya
@lospejos qui peut être évité en utilisant le requireddrapeau comme @RequestHeader(name = "Keep-Alive", required = false) long keepAlivecelui-ci définira le keepAlive sur null s'il n'est pas fourni. Il y a aussi un defaultValuechamp pour l'annotation docs.spring.io/spring-framework/docs/5.0.7.RELEASE/javadoc-api/…
Niccolò
88

Vous pouvez utiliser l' @RequestHeaderannotation avec le HttpHeadersparamètre de méthode pour accéder à tous les en-têtes de demande:

@RequestMapping(value = "/restURL")
public String serveRest(@RequestBody String body, @RequestHeader HttpHeaders headers) {
    // Use headers to get the information about all the request headers
    long contentLength = headers.getContentLength();
    // ...
    StreamSource source = new StreamSource(new StringReader(body));
    YourObject obj = (YourObject) jaxb2Mashaller.unmarshal(source);
    // ...
}
Debojit Saikia
la source
Qu'en est-il du corps de la requête http? Comment accéder aux détails de l'en-tête? pourriez-vous m'expliquer si HttpHeaders est une carte à laquelle j'ai besoin d'une clé pour accéder?
Horse Voice
HttpHeaders a des getters pour obtenir les spécificités de l'en-tête. vous pouvez explorer ce lien pour obtenir les détails: docs.spring.io/spring/docs/3.1.x/javadoc-api/org
...
a modifié ma réponse pour montrer comment vous pouvez accéder au corps de la demande.
Debojit Saikia
1
Pourquoi streamsource est-il nécessaire? Cela semble trop compliqué. Il doit y avoir un moyen plus simple que d'utiliser des flux, etc.
Horse Voice
Ici StringReaderest utilisé pour lire le flux de caractères entrant. StreamSourcefonctionne comme un support pour une source de transformation sous la forme d'un flux de balisage XML.
Debojit Saikia
14

Ma solution dans les paramètres d'en-tête avec l'exemple est user = "test" est:

@RequestMapping(value = "/restURL")
  public String serveRest(@RequestBody String body, @RequestHeader HttpHeaders headers){

System.out.println(headers.get("user"));
}
Armando Cordova
la source