Spring MVC - 如何在Rest Controller中将简单的String作为JSON返回

The*_*ger 123 java rest spring json spring-mvc

我的问题基本上是对这个问题的后续行动.

@RestController
public class TestController
{
    @RequestMapping("/getString")
    public String getString()
    {
        return "Hello World";
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面,Spring会在响应体中添加"Hello World".如何将String作为JSON响应返回?我知道我可以添加引号,但这更像是一个黑客.

请提供任何示例来帮助解释这个概念.

注意:我不希望这直接写入HTTP响应体,我想以JSON格式返回String(我使用我的Controller与RestyGWT,它要求响应是有效的JSON格式).

Sha*_*aun 134

返回text/plain(如在Spring MVC 3 Controller中仅返回字符串消息)或包装你的String是一些对象

public class StringResponse {

    private String response;

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

    // get/set omitted...
}
Run Code Online (Sandbox Code Playgroud)


将您的回复类型设置为 MediaType.APPLICATION_JSON_VALUE

@RequestMapping(value = "/getString", method = RequestMethod.GET,
                produces = MediaType.APPLICATION_JSON_VALUE)
Run Code Online (Sandbox Code Playgroud)

并且你将拥有一个看起来像的JSON

{  "response" : "your string value" }
Run Code Online (Sandbox Code Playgroud)

  • 您还可以返回`Collections.singletonMap("response","您的字符串值")`来实现相同的结果,而无需创建包装类. (108认同)
  • 它需要一个键和一个值是不正确的.单个String或字符串数​​组都是有效的JSON.如果你不同意,也许你可以解释为什么jsonlint网站接受这两个作为有效的JSON. (6认同)
  • 这并没有提供问题的解决方案。问题是响应正文是“Hello World”,但它应该是 JSON 编码为“Hello World”,并用引号使其成为 JSON 字符串。 (6认同)
  • 包装器类如何转换为JSON? (2认同)
  • 我认为返回“ Collections.singleton(“您的字符串值”)“就足够了 (2认同)

pin*_*sia 47

JSON本质上是PHP或JAVA上下文中的String.这意味着可以返回有效JSON的字符串作为响应.以下应该工作.

  @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}";
  }
Run Code Online (Sandbox Code Playgroud)

这对于简单的字符串响应是可以的.但是对于复杂的JSON响应,您应该使用Shaun所描述的包装器类.

  • 这应该是接受的答案,因为这是OP问题的确切答案. (6认同)

The*_*ger 24

自从我发布这个问题以来,我已经开始使用JSONObject(maven 依赖信息)了.特别是与团队合作,我发现当我想要的只是一个简单的String时,更容易期望返回一个String而不是一些包装器对象.

用法示例:

@RestController
public class TestController
{
    @RequestMapping("/getString")
    public String getString()
    {
        return JSONObject.quote("Hello World");
    }
}
Run Code Online (Sandbox Code Playgroud)


Jav*_*ick 19

您可以轻松地返回JSONString财产response如下

@RestController
public class TestController {
    @RequestMapping(value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE)
    public Map getString() {
        return Collections.singletonMap("response", "Hello World");
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 每当您使用 '@RestController' 时,您都不需要使用 '@ResponseBody' (3认同)

Amr*_*afa 9

只需取消注册默认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);
  }
}
Run Code Online (Sandbox Code Playgroud)

使用控制器操作处理程序方法和控制器异常处理程序进行测试:

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

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

最后的说明:

  • extendMessageConverters从Spring 4.1.3开始可用,如果在以前的版本上运行,你可以使用相同的技术configureMessageConverters,它只需要更多的工作.
  • 这是许多其他可能方法的一种方法,如果您的应用程序只返回JSON而没有其他内容类型,则最好跳过默认转换器并添加单个jackson转换器.另一种方法是添加默认转换器,但顺序不同,以便jackson转换器位于字符串1之前.这应该允许控制器操作方法根据响应的媒体类型来指示他们希望如何转换String.

  • `converters.removeIf(c -&gt; c instanceof StringHttpMessageConverter)` (2认同)

小智 9

简单点:

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


Bre*_*eal 6

我知道这个问题已经过时但我也愿意做出贡献:

其他响应之间的主要区别是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;

}
Run Code Online (Sandbox Code Playgroud)

这将返回:

{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}
Run Code Online (Sandbox Code Playgroud)


小智 5

添加produces = "application/json"@RequestMapping像注释:

@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")
Run Code Online (Sandbox Code Playgroud)

提示:作为返回值,我建议使用ResponseEntity<List<T>>type。因为JSON主体中产生的数据根据其规范需要是数组对象,而不是单个简单的string。有时可能会引起问题(例如Angular2中的Observables)。

区别:

返回String的JSON:"example"

返回List<String>的JSON:["example"]