【问题标题】:Simple string as JSON return value in spring rest controllerspring rest控制器中作为JSON返回值的简单字符串
【发布时间】:2014-06-28 04:44:25
【问题描述】:

我们来看看下面这个简单的测试控制器(与 Spring 4.0.3 一起使用):

@RestController
public class TestController
{
    @RequestMapping("/getList")
    public List<String> getList()
    {
        final List<String> list = new ArrayList<>();
        list.add("1");
        list.add("2");
        return list;
    }

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

理论上,两种控制器方法都应该返回有效的 JSON。调用第一个控制器方法确实会返回以下 JSON 数组:

$ curl -i -H "Accept: application/json" http://localhost:8080/getList
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

["1","2"]

但第二个控制器方法返回的字符串不带引号,它不是有效的 JSON 字符串:

$ curl -i -H "Accept: application/json" http://localhost:8080/getString
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

Hello World

为什么会这样?可以配置吗?它是一个错误吗?还是我不理解的功能?

【问题讨论】:

  • 查看在杰克逊转换器之前注册的StringHttpMessageConverter

标签: java json spring spring-mvc jackson


【解决方案1】:

当您返回 String 对象时,Spring MVC 将其解释为要放入响应正文的内容,并且不会进一步修改它。如果您希望将实际字符串作为 JSON 响应,则需要自己引用它或通过 Jackson 显式运行它。

【讨论】:

  • 对我来说听起来很奇怪。根据请求中的Accept 标头,唯一有效的响应必须是内容类型application/json,因此Spring 必须使用Jackson 作为答案,而Jackson 应该生成有效的JSON。在这种情况下,响应根本无效。它的内容类型为 application/json,但未转换为 JSON。
  • @kayahr 但是,如果您想在没有 Jackson 的情况下生成自己的 JSON 字符串(可能是一个非常简单的字符串连接)怎么办?然后 Spring 将不得不重新解析您的响应以检查您。 ResponseBody 表示ResponseBody,它最终是一个字节序列,Spring 只有在不能匹配有问题的 Java 类型时才会执行转换; String 不需要转换。
【解决方案2】:

您可以删除在杰克逊转换器之前注册的StringHttpMessageConverter,就像评论中提到的那样。

/**
 * Unregister the default {@link StringHttpMessageConverter} as we want
 * Strings to be handled by the JSON converter.
 *
 * Our MappingJackson2HttpMessageConverter will deal with strings.
 *
 * @param converters
 *            List of already configured converters
 */
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.removeIf(converter -> converter instanceof StringHttpMessageConverter);
}

【讨论】:

  • 顺便说一句,这可以在 java 8 中写成一个不错的单行:converters.removeIf(converter -&gt; converter instanceof StringHttpMessageConverter);
【解决方案3】:

如果你想返回一个 String 对象,Spring MVC 将其解释为要放入响应正文的内容,并且不会进一步修改它。如果您希望将实际字符串作为 JSON 响应,则需要自己引用它或通过 Jackson 显式运行它。

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

【讨论】:

    【解决方案4】:

    这是我为实现这一目标所做的步骤:

    1. 在 pom 文件中添加依赖:

      <dependency>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-databind</artifactId>
          <version>2.9.3</version>
      </dependency>
      
    2. 像这样在你的方法上添加@ResponseBody注解:

      @RequestMapping(value = "/getCountries", method = RequestMethod.GET)    
      @ResponseBody    
      public List<Country> getCountries() {    
          return countryDAO.list();    
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-06
      • 2015-12-12
      • 2021-08-14
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多