J'ai un simple contrôleur REST écrit dans une application Spring-boot mais je ne sais pas comment implémenter la négociation de contenu pour lui faire retourner JSON ou XML en fonction du paramètre Content-Type dans la demande Quelqu'un pourrait-il m'expliquer ce que je fais mal?
Méthode du contrôleur:
@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
public Message getMessageXML(@RequestParam("text") String text) throws Exception {
Message message = new Message();
message.setDate(new Date());
message.setName("Test");
message.setAge(99);
message.setMessage(text);
return message;
}
J'obtiens toujours JSON lors de l'appel de cette méthode (même si je spécifie le Content-Type
être application/xml
ou text/xml
).
Lorsque j'implémente deux méthodes chacune avec un mappage différent et un type de contenu différent, je peux obtenir du XML à partir du XML mais cela ne fonctionne pas si je spécifie deux mediaTypes dans une seule méthode (comme l'exemple fourni).
Ce que je voudrais, c'est appeler le \message
endpoint et recevoir
Toute aide est appréciée.
EDIT: j'ai mis à jour mon contrôleur pour accepter tous les types de médias
@RequestMapping(value = "/message", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE }, consumes = MediaType.ALL_VALUE)
public Message getMessageXML(@RequestParam("text") String text) throws Exception {
Message message = new Message();
message.setDate(new Date());
message.setName("Vladimir");
message.setAge(35);
message.setMessage(text);
return message;
}
Vous pouvez trouver quelques astuces dans le billet de blog @ RequestMapping with Produces and Consumes au point 6.
Faites attention à la section sur les en-têtes Content-Type et Accept:
@RequestMapping avec des produits et des consommations: nous pouvons utiliser l'en-tête Content-Type et Accept pour connaître le contenu de la demande et quel est le message MIME qu'il souhaite en réponse. Pour plus de clarté, @RequestMapping fournit des variables de production et de consommation où nous pouvons spécifier le type de contenu de la demande pour laquelle la méthode sera invoquée et le type de contenu de la réponse. Par exemple:
@RequestMapping(value="/method6", produces={"application/json","application/xml"}, consumes="text/html") @ResponseBody public String method6(){ return "method6"; }
La méthode ci-dessus peut consommer un message uniquement avec Content-Type en tant que texte/html et est capable de produire des messages de type application/json et application/xml.
Vous pouvez également essayer cette approche différente (en utilisant l'objet ResponseEntity) qui vous permet de trouver le type de message entrant et de produire le message correspondant (en expolant également l'annotation @ResponseBody)
Vous pouvez utiliser ContentNegotiationConfigurer
Tout d'abord, vous devez remplacer la méthode configureContentNegotiation
dans votre classe de configuration:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML);
}
}
favorParameter(true)
- permettant de privilégier les expressions de chemin par rapport au paramètre ou d'accepter les en-têtes.
defaultContentType(MediaType.APPLICATION_JSON)
- définit le type de contenu par défaut. cela signifie que si vous ne transmettez pas d'expression de chemin, Spring générera JSON comme réponse.
mediaType("xml", MediaType.APPLICATION_XML)
- définit la clé d'expression de chemin pour XML.
Maintenant, si vous déclarez votre contrôleur comme:
@Controller
class AccountController {
@RequestMapping(value="/accounts", method=RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public @ResponseBody List<Account> list(Model model, Principal principal) {
return accountManager.getAccounts(principal) );
}
}
et appelez-le quelque chose comme localhost:8080/app/accounts.json
, alors Spring générera JSON comme réponse. Donc, si vous appelez localhost:8080/app/accounts.xml
, Vous recevrez une réponse XML
Vous pouvez trouver plus d'informations à ce sujet ici .