web-dev-qa-db-fra.com

Spring MVC - Comment retourner une chaîne simple en JSON dans Rest Controller

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).

111

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" }
121
Shaun

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.

45
pinkal vansia

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");
    }
}
18
Javasick

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.
  • Il s'agissait d'une approche parmi de nombreuses autres approches possibles. Si votre application ne renvoie jamais que du JSON et aucun autre type de contenu, il vaut mieux ignorer les convertisseurs par défaut et ajouter un convertisseur Jackson unique. Une autre approche consiste à ajouter les convertisseurs par défaut, mais dans un ordre différent, de sorte que le convertisseur Jackson soit antérieur à celui de chaîne. Cela devrait permettre aux méthodes d'action du contrôleur d'indiquer comment elles souhaitent convertir String en fonction du type de support de la réponse.
9
Amr Mostafa

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"}
6
Brenno Leal

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"]

5
Aybars Yuksel

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

3
hugo

Faire simple:

    @GetMapping("/health")
    public ResponseEntity<String> healthCheck() {
        LOG.info("REST request health check");
        return new ResponseEntity<>("{\"status\" : \"UP\"}", HttpStatus.OK);
    }
1
samarone

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.

1
Ranuka