Ma question est essentiellement une suite à la question this .
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return "Hello World";
}
}
Dans ce qui précède, Spring ajouterait "Hello World" dans le corps de la réponse. Comment puis-je retourner une chaîne sous forme de réponse JSON? Je comprends que je pourrais ajouter des citations, mais cela ressemble plus à un hack.
Veuillez fournir des exemples pour aider à expliquer ce concept.
Remarque: Je ne veux pas que cela soit écrit directement dans le corps de la réponse HTTP, je veux renvoyer la chaîne au format JSON (j'utilise mon contrôleur avec RestyGWT qui nécessite que la réponse soit au format JSON valide).
Retournez text/plain
(comme dans Renvoie uniquement le message de chaîne du contrôleur Spring MVC ) OR enroulez votre chaîne comme un objet.
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// get/set omitted...
}
Définissez votre type de réponse sur application/json
@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")
et vous aurez un JSON qui ressemble à
{ "response" : "your string value" }
JSON est essentiellement une chaîne dans le contexte PHP ou Java. Cela signifie qu'une chaîne de caractères valide JSON peut être renvoyée en réponse. Suivre devrait fonctionner.
@RequestMapping(value="/user/addUser", method=RequestMethod.POST)
@ResponseBody
public String addUser(@ModelAttribute("user") User user) {
if (user != null) {
logger.info("Inside addIssuer, adding: " + user.toString());
} else {
logger.info("Inside addIssuer...");
}
users.put(user.getUsername(), user);
return "{\"success\":1}";
}
C'est correct pour une réponse en chaîne simple. Mais pour les réponses JSON complexes, vous devez utiliser la classe wrapper décrite par Shaun.
Dans un projet, nous avons résolu ce problème en utilisant JSONObject (maven informations de dépendance ). Nous avons choisi cette option car nous avons préféré renvoyer une simple chaîne plutôt qu'un objet wrapper. Une classe d'assistance interne peut facilement être utilisée à la place si vous ne souhaitez pas ajouter de nouvelle dépendance.
Exemple d'utilisation:
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return JSONObject.quote("Hello World");
}
}
Vous pouvez facilement retourner JSON
avec String
dans la propriété response
comme suit
@RestController
public class TestController {
@RequestMapping(value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE)
public Map getString() {
return Collections.singletonMap("response", "Hello World");
}
}
Désenregistrer simplement l'instance par défaut StringHttpMessageConverter
:
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
/**
* Unregister the default {@link StringHttpMessageConverter} as we want Strings
* to be handled by the JSON converter.
*
* @param converters List of already configured converters
* @see WebMvcConfigurationSupport#addDefaultHttpMessageConverters(List)
*/
@Override
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.stream()
.filter(c -> c instanceof StringHttpMessageConverter)
.findFirst().ifPresent(converters::remove);
}
}
Testé avec les méthodes de gestionnaire d’action de contrôleur et les gestionnaires d’exception de contrôleur:
@RequestMapping("/foo")
public String produceFoo() {
return "foo";
}
@ExceptionHandler(FooApiException.class)
public String fooException(HttpServletRequest request, Throwable e) {
return e.getMessage();
}
Notes finales:
extendMessageConverters
est disponible depuis Spring 4.1.3. Si vous utilisez une version précédente, vous pouvez implémenter la même technique avec configureMessageConverters
, cela demande un peu plus de travail.Je sais que cette question est ancienne, mais j'aimerais aussi contribuer:
La principale différence entre les autres réponses est le retour de hashmap.
@GetMapping("...")
@ResponseBody
public HashMap<String, Object> endPointExample(...) {
HashMap<String, Object> rtn = new LinkedHashMap<String, Object>();
rtn.put("pic", image);
rtn.put("potato", "King Potato");
return rtn;
}
Cela retournera:
{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}
Ajouter produces = "application/json"
dans @RequestMapping
annotation comme:
@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")
Astuce: comme valeur de retour, je recommande d'utiliser le type ResponseEntity<List<T>>
. Parce que les données produites dans le corps JSON doivent être un tablea ou un objet conformément à ses spécifications, plutôt qu'un simple simple chaîne. Cela peut parfois poser problème (par exemple, Observables dans Angular2).
Différence:
retourné String
comme json: "example"
a retourné List<String>
comme json: ["example"]
Ajoutez l'annotation @ResponseBody
, qui écrira les données de retour dans le flux de sortie.
Faire simple:
@GetMapping("/health")
public ResponseEntity<String> healthCheck() {
LOG.info("REST request health check");
return new ResponseEntity<>("{\"status\" : \"UP\"}", HttpStatus.OK);
}
Au printemps MVC 4, le type de réponse par défaut pour les objets est JSON. Donc, tout ce que vous avez à faire est d’envelopper votre chaîne dans un objet.
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// getters and setters
}
Aucune modification du contrôleur, sauf le retour de StringResponse
à la place de la chaîne.