【问题标题】:Why does Spring MVC report "No converter found for return value of type: class org.json.JSONObject"?为什么 Spring MVC 报告“No converter found for return value of type: class org.json.JSONObject”?
【发布时间】:2017-02-03 15:20:14
【问题描述】:

我想返回一个由两个字符串组成的 JSON,但不知道如何实现。这是我的代码:

 @PostMapping
public ResponseEntity<> createUser(@RequestBody User user ) {

    JSONObject responseJson = new JSONObject();

    if (userService.userExists(user)) {

        responseJson.put("status", "User with that username already exists.");

        return new ResponseEntity<>(responseJson, HttpStatus.BAD_REQUEST);
    }

    responseJson.put("status", "User created.");

    return new ResponseEntity<>(responseJson, HttpStatus.CREATED);
}

我的 pom.xml 中有 Json » 20160810 和 com.fasterxml.jackson.core,但我仍然收到 java.lang.IllegalArgumentException: No converter found for return value of type: class org.json.JSONObject 为什么 Jackson 不自动转换我的 JSON?这是一个标准的,只是简单的键:值。也许有更好的方法来使用 jackson.core 中的某个类创建简单的 JSON,这样我就不必在我的项目中包含 Json lib 并且 jackson 会自动转换它们?

【问题讨论】:

    标签: java json spring-mvc


    【解决方案1】:

    我不知道您为什么要使用两个 JSON 解析库。与其创建 JSONObject,不如创建 Jackson 等效的 ObjectNode。

    假设您可以访问 Spring MVC 堆栈使用的 ObjectMapper

    @Autowired
    private ObjectMapper objectMapper;
    

    使用它来创建和填充ObjectNode

    ObjectNode jsonObject = mapper.createObjectNode();
    jsonObject.put("status", "User with that username already exists.");
    // don't forget to change return type to support this
    return new ResponseEntity<>(jsonObject, HttpStatus.BAD_REQUEST);
    

    由于这是 Jackson 类型,Jackson 知道如何对其进行序列化。

    它不知道如何序列化JSONObject。以下部分解释来自我的回答here。

    本质上,Spring MVC 使用HandlerMethodReturnValueHandler 实现来处理由@RequestMapping (@PostMapping) 注释方法返回的值。对于ResponseEntity,该实现是HttpEntityMethodProcessor。

    这个实现简单地遍历HttpMessageConverter实例的集合,检查一个实例是否可以序列化ResponseEntity的body,如果可以就使用它。

    不幸的是,Jackson 的HttpMessageConverter 实现MappingJackson2HttpMessageConverter 使用ObjectMapper 序列化这些对象,而ObjectMapper 无法序列化JSONObject,因为它无法发现类中的任何属性(即bean getter) .

    Jackson 的HttpMessageConverter 做不到,其他默认注册的也做不到。这就是 Spring MVC 报告“没有转换器”的原因。

    org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type: class org.json.JSONObject
    

    另一种解决方案是自己将JSONObject 序列化为String,并将其传递给ResponseEntity。显然你会想要改变你的返回类型来支持String。在这种情况下,Spring MVC 将使用StringHttpMessageConverter。但是,您需要自己指定 application/json 内容类型,因为它不会添加它。例如,

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    return new ResponseEntity<>(responseJson.toString(), headers, HttpStatus.BAD_REQUEST);
    

    【讨论】:

      【解决方案2】:

      Jackson 不知道 org.json.JSONObject,使用 JsonNode 代替 key/value 对。

      评论后更新:

      你能给我写一个你会如何使用它的例子吗?我觉得有点 混乱

      @PostMapping
      public ResponseEntity<JsonNode> createUser(@RequestBody User user) {
              ObjectMapper objectMapper = new ObjectMapper();
      
              Map<String, String> responseJson = new HashMap<>();
              if (userService.userExists(user)) {
                  responseJson.put("status",
                          "User with that username already exists.");
                  JsonNode jsonNode = objectMapper.valueToTree(responseJson);
                  return new ResponseEntity<JsonNode>(jsonNode,
                          HttpStatus.BAD_REQUEST);
              }
              responseJson.put("status", "User created.");
              JsonNode jsonNode = objectMapper.valueToTree(responseJson);
              return new ResponseEntity<>(jsonNode, HttpStatus.CREATED);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-07-17
        • 1970-01-01
        • 2015-03-23
        相关资源
        最近更新 更多