Spring MVC - comment rendre une chaîne simple comme JSON dans le contrôleur Rest

ma question est essentiellement une suite à cette question .

@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 réponse. Comment retourner une chaîne comme réponse JSON? Je comprends que je puisse ajouter des citations, mais ça ressemble plus à un piratage.

veuillez fournir des exemples pour expliquer ce concept.

Note: je n'ai pas je veux que cela soit écrit directement au corps de réponse HTTP, je veux retourner la chaîne au format JSON (j'utilise mon contrôleur avec RestyGWT qui exige que la réponse soit dans JSON valide format.)

85
demandé sur Community 2015-06-17 17:58:37

10 réponses

soit retourner text/plain (comme dans Return only string message from Spring MVC 3 Controller ) soit envelopper votre chaîne de caractères est un objet quelconque

public class StringResponse {

    private String response;

    public StringResponse(String s) { 
       this.response = s;
    }

    // get/set omitted...
}



Définissez votre type de réponse à application/json

@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")

et vous aurez un JSON qui ressemble à

{  "response" : "your string value" }
98
répondu Shaun 2017-05-23 12:10:48

JSON est essentiellement une chaîne de caractères en PHP ou en JAVA. Cela signifie que la chaîne de caractères qui est valide JSON peut être retournée en réponse. Suivant 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}";
  }

ceci est correct pour la réponse de chaîne simple. Mais pour une réponse JSON complexe, vous devez utiliser la classe wrapper telle que décrite par Shaun.

35
répondu pinkal vansia 2015-10-27 06:08:10

depuis que j'ai posté cette question, j'ai commencé à utiliser JSONObject (maven info dépendance ). En travaillant surtout avec une équipe, je trouve qu'il est plus facile de s'attendre à ce qu'une chaîne de caractères soit retournée plutôt qu'un objet enveloppant quand tout ce que je veux c'est une simple chaîne de caractères.

Exemple D'Usage:

@RestController
public class TestController
{
    @RequestMapping("/getString")
    public String getString()
    {
        return JSONObject.quote("Hello World");
    }
}
18
répondu The Gilbert Arenas Dagger 2016-06-14 18:31:05

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");
    }
}
12
répondu D0dger 2018-02-23 11:20:39

désinscrire simplement la valeur par défaut StringHttpMessageConverter instance:

@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é à la fois avec les méthodes de gestion de l'action du contrôleur et avec les méthodes de gestion des exceptions du contrôleur:

@RequestMapping("/foo")
public String produceFoo() {
  return "foo";
}

@ExceptionHandler(FooApiException.class)
public String fooException(HttpServletRequest request, Throwable e) {
  return e.getMessage();
}

Final notes:

  • extendMessageConverters est disponible depuis le printemps 4.1.3, si sont en cours d'exécution sur une version précédente , vous pouvez mettre en œuvre la même technique en utilisant configureMessageConverters , il suffit d'un peu plus de travail.
  • C'était une approche parmi beaucoup d'autres approches possibles, si votre application ne renvoie que JSON et aucun autre type de contenu, Vous feriez mieux de sauter les convertisseurs par défaut et d'ajouter un seul convertisseur jackson. Une autre approche consiste à ajouter les convertisseurs par défaut mais dans un ordre différent afin que le convertisseur jackson soit antérieur à celui de la chaîne. Cela devrait permettre aux méthodes d'action du controller de dicter comment ils veulent que la chaîne soit convertie en fonction du type de média de la réponse.
5
répondu Amr Mostafa 2016-06-19 10:21:29

ajouter produces = "application/json" dans @RequestMapping annotation comme:

@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")

indice: comme valeur de retour, je recommande d'utiliser le type ResponseEntity<List<T>> . Parce que les données produites dans le corps de JSON doivent être un tableau ou un objet selon ses spécifications, plutôt qu'une simple chaîne . Il peut parfois causer des problèmes (par exemple Observables en Angular2).

Différence:

retourné String json: "example"

retourné List<String> json: ["example"]

4
répondu Aybars Yuksel 2017-05-16 18:45:35

ajouter @ResponseBody annotation, qui écrira les données de retour dans le flux de sortie.

4
répondu hugo 2017-06-28 20:17:03

je sais que cette question Est ancienne mais je voudrais y contribuer aussi:

la principale différence entre les autres réponses est le retour 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;

}

Ce sera de retour:

{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}
4
répondu Brenno Leal 2018-07-16 14:19:01

au printemps MVC 4 le type de réponse par défaut pour les objets est JSON. Tout ce que vous avez à faire, c'est envelopper votre ficelle dans un objet.

    public class StringResponse {

   private String response;

   public StringResponse(String s) { 
       this.response = s;
   }

    // getters and setters 
}

aucune modification au contrôleur, sauf retourner le StringResponse à la place de la chaîne.

1
répondu Ranuka 2018-02-14 05:36:19

ajouter cette annotation à votre méthode

@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")
-3
répondu Dali 2017-01-28 13:54:24