Spring 4 @RequestMapping - consomme vs en-têtes?

J'apprends comment créer des services Web RESTful en utilisant Spring 4, et une chose dont je ne suis pas certain est dans @RequestMapping. J'ai vu des exemples où on utilise headers = "Accepter = application/xml" et d'autres exemples utilisant consume (ou produit) = "application/xml" .

Par exemple, dans ma propre classe @RestController, j'ai cette fonction ...

// POST
@RequestMapping(method = RequestMethod.POST, headers = "Accept=application/xml")
public User create(@RequestBody User user) {
    LOG.info("User = " + user.toString());
return userService.create(user);
}

Quelle est la différence entre utiliser headers = "Accepter = application/xml" et consommer = "application/xml"? Ou même utiliser headers = "contenu -type = application/xml "?

Quelqu'un pourrait-il expliquer les différences entre les en-têtes et les consommations/produits, et quand chacun est utilisé?

0

2 Réponses

Comme le javadoc de HeadersRequestCondition (qui gère la valeur fournie dans l'attribut headers d'une annotation @RequestMapping )

Expressions passées au constructeur avec les noms d'en-tête 'Accepter' ou   'Content-Type' sont ignorés. Voir ConsumesRequestCondition et    < code> ProducesRequestCondition pour ceux-là.

N'utilisez donc pas ces en-têtes dans les en-têtes . Utilisez les attributs produit et consomme pour Accept et Content-Type .

Quant à la façon de les utiliser, la documentation donne des exemples: pour consomme et pour produit .

0
ajouté
@VadimKirilchuk Ils sont ignorés dans HeadersRequestCondition . Voir le code source, ici . Cependant, ces mêmes valeurs sont également passées à ProducesRequestCondition et ConsumesRequestCondition lors de la construction d'un RequestMappingInfo pour le RequestMappingHandlerMapping . Voir
ajouté l'auteur Sotirios Delimanolis, source
@VadimKirilchuk Aussi, la citation dans la réponse provient du javadoc.
ajouté l'auteur Sotirios Delimanolis, source
Je ne pense pas que ce soit ignoré, il n'y a rien dans la documentation officielle. De plus, cela fonctionne. Quoi qu'il en soit, l'utilisation de produits et de consommations est préférable.
ajouté l'auteur Vadim Kirilchuk, source
Il y a un petit malentendu entre nous. Je suis totalement d'accord avec vous que HeaderRequestCondition ignore les en-têtes Accept et Content-type et que nous voyons dans le code source. Mais la question initiale était de placer l'en-tête dans le paramètre "headers" et cela fonctionne parfaitement, juste parce que, comme vous l'avez dit, les "auditeurs" sont également passés à Prod
ajouté l'auteur Vadim Kirilchuk, source

SHORT ANSWER
In the example you have above, using headers = "Accept=application/xml" or produces = "application/xml" will both respond to the client the same way i.e. send a response to the client with xml representation.

LONGER ANSWER
i. Headers
For RESTful web services, the client (e.g. your browser) sends a request (e.g. GET, POST, etc.) to a server, and the server will send a response back. This is an HTTP Transaction. Both the request and response have HTTP header fields ("headers"), which define the operating parameters of an HTTP transaction (I will refer to the headers for client request as "request headers", and these differ from headers from server response "response headers").

Dans le cadre de la requête que votre navigateur envoie au serveur, il existe différents en-têtes de requêtes et certains exemples incluent Accepter , Connexion , Content-Length etc. et chacun de ces en-têtes a sa propre fonction (voir la liste complète des en-têtes ici: https://en.wikipedia.org/wiki/ List_of_HTTP_header_fields ).

En utilisant votre exemple de code, si un client fait une requête POST, Spring vérifie l'en-tête de la requête et s'il trouve un en-tête Accept avec une valeur de application/xml , il mappera la requête à la méthode create ci-dessus (et dans votre cas le serveur retournera une représentation de réponse xml au client).

Permettez-moi de modifier l'élément headers dans le code fourni:

@RequestMapping(method = RequestMethod.POST, headers = "Connection=keep-alive")
public User create(@RequestBody User user) {
 ...
}

Notez que l'élément headers a maintenant la valeur Connection = keep-alive . Si un client envoie une requête POST, Spring vérifiera l'en-tête de la requête et s'il trouve un en-tête Connection avec la valeur keep-alive , il mappera requête client à la méthode create ci-dessus.

ii. Produces and Consumes
If you used produces="application/xml" for the create method, this means a client request is only mapped to the create method if the client's Accept header matches application/xml. This essentially is the client saying, "Hey server, I prefer to accept your response in xml representation, so send your response to me in XML". Effectively, the produces="application/xml" is also the server saying, "Hey client, I can only produce responses for you in xml representation, so I will send you that format". Link to Spring documentation reference.

Si vous avez utilisé consumes = "application/xml" pour la méthode create , cela signifie qu'une requête client est uniquement mappée à la méthode create si L'en-tête Content-Type du client correspond à application/xml (l'en-tête de demande Content-Type décrit la représentation de la requête client). C'est essentiellement le serveur qui dit: "Hey client, je ne peux consommer que des requêtes en représentation XML, alors envoyez-moi ce format".

SUMMARY
The headers element within the @RequestMapping annotation can take different request headers (Accept, Connection, Cache-Control etc.), but the produces element is only concerned with the Accept request header and the consumes element is only concerned with the Content-Type request header.

0
ajouté
Une idée pourquoi cela ne fonctionne pas ?
ajouté l'auteur Stefan Falk, source
Cette réponse devrait être marquée comme une réponse acceptée. Au fait merci Alex pour la réponse détaillée et informative.
ajouté l'auteur Khalid ElSayed, source