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

时间:2015-06-17 14:58:38

标签: java json spring rest spring-mvc

我的问题基本上是对this问题的跟进。

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

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

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

  

注意:我不想直接写入HTTP Response主体,我想以JSON格式返回String(我正在使用我的Controller   使用RestyGWT,要求响应处于有效的JSON状态   格式)。

12 个答案:

答案 0 :(得分:113)

返回text/plain(如Return only string message from Spring MVC 3 Controller中所示)或包裹你的String是某个对象

public class StringResponse {

    private String response;

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

    // get/set omitted...
}


将您的回复类型设置为application/json

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

并且您将拥有一个类似于

的JSON
{  "response" : "your string value" }

答案 1 :(得分:41)

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}";
  }

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

答案 2 :(得分:21)

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

示例用法:

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

答案 3 :(得分:17)

您可以轻松地在complete_name属性JSON中返回String,如下所示

response

答案 4 :(得分:8)

只需取消注册默认的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);
  }
}

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

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

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

最后的说明:

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

答案 5 :(得分:6)

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

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

@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;

}

这将返回:

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

答案 6 :(得分:4)

produces = "application/json"注释中添加@RequestMapping,如:

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

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

差异:

以json:String

返回"example"

以json:List<String>

返回["example"]

答案 7 :(得分:3)

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

答案 8 :(得分:1)

在Spring MVC 4中,对象的默认响应类型是JSON。所以你需要做的就是将String包装在一些Object中。

    public class StringResponse {

   private String response;

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

    // getters and setters 
}

除了返回StringResponse而不是String之外,不对控制器进行任何修改。

答案 9 :(得分:1)

简单点:

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

答案 10 :(得分:0)

这个问题使我发疯了:Spring是一种强大的工具,但是,如果没有丑陋的黑客,像将输出字符串写为JSON这样简单的事情似乎是不可能的。

我的解决方案(在Kotlin中)是侵入性最低且最透明的解决方案,它是使用控制器建议并检查请求是否到达了一组特定的端点(通常是REST API,因为我们通常希望返回所有答案)此处为JSON,而不根据返回的数据是纯字符串(“不要进行JSON反序列化!”)还是其他方式(“进行JSON反序列化!”)在前端进行特殊化。积极的一面是,控制器保持不变,没有被黑客入侵。

supports方法确保StringHttpMessageConverter处理的所有请求(例如,处理所有返回纯字符串的控制器的输出的转换器)都在{{1}中处理}方法,我们控制在哪种情况下我们想要中断并将输出转换为JSON(并相应地修改标头)。

beforeBodyWrite

我希望将来我们会得到一个简单的注释,在其中可以覆盖应将哪个@ControllerAdvice class StringToJsonAdvice(val ob: ObjectMapper) : ResponseBodyAdvice<Any?> { override fun supports(returnType: MethodParameter, converterType: Class<out HttpMessageConverter<*>>): Boolean = converterType === StringHttpMessageConverter::class.java override fun beforeBodyWrite( body: Any?, returnType: MethodParameter, selectedContentType: MediaType, selectedConverterType: Class<out HttpMessageConverter<*>>, request: ServerHttpRequest, response: ServerHttpResponse ): Any? { return if (request.uri.path.contains("api")) { response.getHeaders().contentType = MediaType.APPLICATION_JSON ob.writeValueAsString(body) } else body } } 用于输出。

答案 11 :(得分:-3)

将此注释添加到方法

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