Java Spring MVC - 如何在 Rest Controller 中将简单字符串作为 JSON 返回

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30895286/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 10:20:27  来源:igfitidea点击:

Spring MVC - How to return simple String as JSON in Rest Controller

javajsonspringrestspring-mvc

提问by The Gilbert Arenas Dagger

My question is essentially a follow-up to thisquestion.

我的问题本质上是对这个问题的跟进。

@RestController
public class TestController
{
    @RequestMapping("/getString")
    public String getString()
    {
        return "Hello World";
    }
}

In the above, Spring would add "Hello World" into the response body. How can I return a String as a JSON response? I understand that I could add quotes, but that feels more like a hack.

在上面,Spring 会将“Hello World”添加到响应正文中。如何将字符串作为 JSON 响应返回?我知道我可以添加引号,但这感觉更像是一种黑客攻击。

Please provide any examples to help explain this concept.

请提供任何示例以帮助解释此概念。

Note:I don't want this written straight to the HTTP Response body, I want to return the String in JSON format (I'm using my Controller with RestyGWTwhich requires the response to be in valid JSON format).

注意:我不希望将其直接写入 HTTP 响应正文,我想以 JSON 格式返回字符串(我将我的控制器与RestyGWT一起使用,它要求响应采用有效的 JSON 格式)。

采纳答案by Shaun

Either return text/plain(as in Return only string message from Spring MVC 3 Controller) OR wrap your String is some object

要么返回text/plain(如仅返回来自 Spring MVC 3 控制器的字符串消息)或将您的 String 包装为某个对象

public class StringResponse {

    private String response;

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

    // get/set omitted...
}


Set your response type to MediaType.APPLICATION_JSON_VALUE(= "application/json")


将您的响应类型设置为MediaType.APPLICATION_JSON_VALUE(= "application/json")

@RequestMapping(value = "/getString", method = RequestMethod.GET,
                produces = MediaType.APPLICATION_JSON_VALUE)

and you'll have a JSON that looks like

你会得到一个看起来像的 JSON

{  "response" : "your string value" }

回答by Dali

Add this annotation to your method

将此注释添加到您的方法中

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

回答by pinkal vansia

JSON is essentially a String in PHP or JAVA context. That means string which is valid JSON can be returned in response. Following should work.

JSON 本质上是 PHP 或 JAVA 上下文中的字符串。这意味着可以返回有效的 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}";
  }

This is okay for simple string response. But for complex JSON response you should use wrapper class as described by Shaun.

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

回答by The Gilbert Arenas Dagger

In one project we addressed this using JSONObject(maven dependency info). We chose this because we preferred returning a simple String rather than a wrapper object. An internal helper class could easily be used instead if you don't want to add a new dependency.

在一个项目中,我们使用JSONObject(maven依赖信息)解决了这个问题。我们选择这个是因为我们更喜欢返回一个简单的 String 而不是一个包装对象。如果您不想添加新的依赖项,可以轻松地改用内部帮助程序类。

Example Usage:

示例用法:

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

回答by Amr Mostafa

Simply unregister the default StringHttpMessageConverterinstance:

只需注销默认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);
  }
}

Tested with both controller action handler methods and controller exception handlers:

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

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

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

Final notes:

最后说明:

  • extendMessageConvertersis available since Spring 4.1.3, if are running on a previous version you can implement the same technique using configureMessageConverters, it just takes a little bit more work.
  • This was one approach of many other possible approaches, if your application only ever returns JSON and no other content types, you are better off skipping the default converters and adding a single Hymanson converter. Another approach is to add the default converters but in different order so that the Hymanson converter is prior to the string one. This should allow controller action methods to dictate how they want String to be converted depending on the media type of the response.
  • extendMessageConverters从 Spring 4.1.3 开始可用,如果在以前的版本上运行,您可以使用 实现相同的技术configureMessageConverters,只需要多做一点工作。
  • 这是许多其他可能方法中的一种,如果您的应用程序只返回 JSON 而没有其他内容类型,则最好跳过默认转换器并添加单个 Hymanson 转换器。另一种方法是添加默认转换器,但顺序不同,以便 Hymanson 转换器在字符串之前。这应该允许控制器操作方法根据响应的媒体类型来决定如何转换 String。

回答by Aybars Yuksel

Add produces = "application/json"in @RequestMappingannotation like:

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

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

Hint: As a return value, i recommend to use ResponseEntity<List<T>>type. Because the produced data in JSON body need to be an arrayor an objectaccording to its specifications, rather than a single simple string. It may causes problems sometimes (e.g. Observables in Angular2).

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

Difference:

区别:

returned Stringas json: "example"

返回String的JSON:"example"

returned List<String>as json: ["example"]

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

回答by hugo

Add @ResponseBodyannotation, which will write return data in output stream.

添加@ResponseBody注释,它将在输出流中写入返回数据。

回答by Javasick

You can easily return JSONwith Stringin property responseas following

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

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

回答by Brenno Leal

I know that this question is old but i would like to contribute too:

我知道这个问题很老,但我也想做出贡献:

The main difference between others responses is the hashmap return.

其他响应之间的主要区别是哈希图返回。

@GetMapping("...")
@ResponseBody
public Map<String, Object> endPointExample(...) {

    Map<String, Object> rtn = new LinkedHashMap<>();

    rtn.put("pic", image);
    rtn.put("potato", "King Potato");

    return rtn;

}

This will return:

这将返回:

{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}

回答by samarone

Make simple:

简单点:

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