为什么Spring MVC报告“没有为类型的返回值找到转换器:class org.json.JSONObject”?

时间:2017-02-03 15:20:14

标签: java json spring-mvc

我想返回由两个字符串组成的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 » 20160810com.fasterxml.jackson.core,我仍然得到java.lang.IllegalArgumentException: No converter found for return value of type: class org.json.JSONObject为什么杰克逊不会自动转换我的JSON?这是一个标准的,只是简单的关键:价值。也许有更好的方法来创建使用jackson.core中的一些类的简单JSON,所以我不必在我的项目中包含Json lib并且jackson自动转换它们?

2 个答案:

答案 0 :(得分:2)

我不知道你为什么要使用两个JSON解析库。而不是创建JSONObject,而是创建杰克逊的等效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类型,杰克逊知道如何序列化它。

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

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

此实现只是循环遍历HttpMessageConverter个实例的集合,检查实例是否可以序列化body的{​​{1}},并在可能的情况下使用它。

不幸的是,杰克逊的ResponseEntity实施MappingJackson2HttpMessageConverter使用HttpMessageConverter来序列化这些对象,ObjectMapper无法序列化ObjectMapper,因为它无法发现任何类中的属性(即bean getter)。

杰克逊的JSONObject无法做到,默认情况下注册的所有其他人也无法做到。这就是Spring MVC报道“没有转换器”的原因。

HttpMessageConverter

另一种解决方案是将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。在这种情况下,Spring MVC将使用StringHttpMessageConverter。但是,您需要自己指定String内容类型,因为它不会添加它。例如,

application/json

答案 1 :(得分:0)

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