Je travaille avec Spring 4.0.7
À propos de Spring MVC, à des fins de recherche, j’ai les compétences suivantes:
@RequestMapping(value="/getjsonperson",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Person getJSONPerson(){
logger.info("getJSONPerson - getjsonperson");
return PersonFactory.createPerson();
}
@RequestMapping(value="/getperson.json", method=RequestMethod.GET)
public @ResponseBody Person getPersonJSON(){
logger.info("getPerson - getpersonJSON");
return PersonFactory.createPerson();
}
Chacun fonctionne bien, observez les deux pour JSON, avec et sans extension:
Pareil pour XML
@RequestMapping(value="/getxmlperson",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_XML_VALUE
)
public @ResponseBody Person getXMLPerson(){
logger.info("getXMLPerson - getxmlperson");
return PersonFactory.createPerson();
}
@RequestMapping(value="/getperson.xml", method=RequestMethod.GET)
@ResponseBody
public Person getPersonXML(){
logger.info("getPerson - getpersonXML");
return PersonFactory.createPerson();
}
Chacun fonctionne bien, observez les deux formats XML, avec et sans extension:
Maintenant à propos de reposant , j'ai les éléments suivants:
@RequestMapping(value="/person/{id}/",
method=RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public ResponseEntity<Person> getPersonCustomizedRestrict(@PathVariable Integer id){
Person person = personMapRepository.findPerson(id);
return new ResponseEntity<>(person, HttpStatus.FOUND);//302
}
Observez le MediaType
, il est mélangé, pour JSON et XML
Avec RestTemplate je peux indiquer la valeur Accept
if(type.equals("JSON")){
logger.info("JSON");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
}
else if(type.equals("XML")){
logger.info("XML");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_XML));
}
….
ResponseEntity<Person> response =
restTemplate.exchange("http://localhost:8080/spring-utility/person/{id}/customizedrestrict",
HttpMethod.GET,
new HttpEntity<Person>(headers),
Person.class,
id
);
Jusqu'ici, je peux donc utiliser une URL/URI pour obtenir des données aux formats XML ou JSON. Ça fonctionne bien
Mon problème est avec Spring MVC… il suffit de considérer
@RequestMapping(value="/{id}/person",
method=RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public @ResponseBody Person getPerson(@PathVariable Integer id){
return personMapRepository.findPerson(id);
}
Je peux appeler ou activer cette méthode de gestionnaire (@RequestMapping
) par:
Accept
(JSON par exemple)Headers
, je peux régler le Accept
Première question:
Mais pour un lien commun? Comment puis-je définir la valeur Accept
? est possible?
J'ai pensé d'une autre manière à résoudre ce problème.
http://localhost:8080/spring-utility/person/getpersonformat?format=json
http://localhost:8080/spring-utility/person/getpersonformat?format=xml
Observer:
?format
Donc
@RequestMapping(value="/getpersonformat",
method=RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE})
public @ResponseBody Person getPerson(@RequestParam String format){
return personMapRepository.findPerson(id);
}
Deuxième question:
Quel code pour la méthode présentée ci-dessus doit être ajouté pour personnaliser le format du type de retour? Je veux dire, JSON ou XML, est possible?
J'ai pensé dans ce qui suit:
@RequestMapping(value="/getpersonformataltern",
method=RequestMethod.GET
produces={MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_XML_VALUE}
)
public ResponseEntity<Person> getPersonFormat(@RequestParam String format){
logger.info("getPersonFormat - format: {}", format);
HttpHeaders httpHeaders = new HttpHeaders();
if(format.equals("json")){
logger.info("Ok JSON");
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
}
else{
logger.info("Ok XML");
httpHeaders.setContentType(MediaType.APPLICATION_XML);
}
return new ResponseEntity<>(PersonFactory.createPerson(), httpHeaders, HttpStatus.OK);
}
Mais:
Si j'exécute l'URL:
http://localhost:8080/spring-utility/person/getpersonformataltern?format=json
Je reçois
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
<id>1</id>
<firstName>Manuel</firstName>
<lastName>Jordan</lastName>
…
</person>
Oui dans [~ # ~] xml [~ # ~] !
Remarque : Je peux confirmer l'impression de la console Ok JSON
Si j'exécute l'URL:
http://localhost:8080/spring-utility/person/getpersonformataltern?format=xml
Je reçois
This XML file does not appear to have any style information associated with it.
The document tree is shown below.
<person>
<id>1</id>
<firstName>Manuel</firstName>
<lastName>Jordan</lastName>
…
</person>
Troisième question
Quel code pour la méthode ci-dessus doit être ajouté pour corriger la sortie JSON? Je ne sais pas ce qui ne va pas ou manque.
Il y a trois questions.
Merci
Alpha
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
Map<String,MediaType> mediaTypes = new LinkedHashMap<>();
mediaTypes.put("json", MediaType.APPLICATION_JSON);
mediaTypes.put("xml", MediaType.APPLICATION_XML);
configurer.mediaTypes(mediaTypes);
configurer.defaultContentType(MediaType.TEXT_HTML);
}
L'utilisation de l'en-tête Accept est très facile à obtenir au format json ou xml à partir du service REST.
Ceci est mon contrôleur, jetez un oeil produit section.
@RequestMapping(value = "properties", produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE}, method = RequestMethod.GET)
public UIProperty getProperties() {
return uiProperty;
}
Afin de consommer le service REST, nous pouvons utiliser le code ci-dessous où l'en-tête peut être MediaType.APPLICATION_JSON_VALUE ou MediaType.APPLICATION_XML_VALUE
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", header);
HttpEntity entity = new HttpEntity(headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.exchange("http://localhost:8080/properties", HttpMethod.GET, entity,String.class);
return response.getBody();
Edit 01:
Afin de travailler avec application/xml
, ajoute cette dépendance
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
Tous vos problèmes sont que vous mélangez la négociation du type de contenu avec la transmission de paramètres. Ce sont des choses à différents niveaux. Plus précisément, pour votre question 2, vous avez construit l’en-tête de la réponse avec le type de support que vous souhaitez renvoyer. La négociation de contenu réelle est basée sur le type de support accepté dans l'en-tête de votre demande, pas dans l'en-tête de la réponse. Au moment où l'exécution atteint l'implémentation de la méthode getPersonFormat, je ne sais pas si la négociation de contenu a été effectuée ou non. Dépend de la mise en œuvre. Si ce n'est pas le cas et que vous souhaitez faire fonctionner l'objet, vous pouvez écraser le type d'acceptation de l'en-tête de demande avec ce que vous voulez renvoyer.
return new ResponseEntity <> (PersonFactory.createPerson (), httpHeaders, HttpStatus.OK);
J'ai préféré utiliser le filtre params pour le type de contenu centré sur les paramètres. Je pense que cela devrait fonctionner en conjonction avec l'attribut de produit.
@GetMapping(value="/person/{id}/",
params="format=json",
produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Person> getPerson(@PathVariable Integer id){
Person person = personMapRepository.findPerson(id);
return ResponseEntity.ok(person);
}
@GetMapping(value="/person/{id}/",
params="format=xml",
produces=MediaType.APPLICATION_XML_VALUE)
public ResponseEntity<Person> getPersonXML(@PathVariable Integer id){
return GetPerson(id); // delegate
}