Why does Spring MVC report “No converter found for return value of type: class org.json.JSONObject”?

后端 未结 2 560
猫巷女王i
猫巷女王i 2021-01-27 03:45

I want to return a JSON made of two strings and don\'t know how to implement it. Here is my code:

 @PostMapping
public ResponseEntity<> createUser(@Request         


        
2条回答
  •  天涯浪人
    2021-01-27 04:40

    I don't know why you're using two JSON parsing libraries. Instead of creating a JSONObject, create Jackson's equivalent ObjectNode.

    Assuming you have access to the ObjectMapper used by your Spring MVC stack

    @Autowired
    private ObjectMapper objectMapper;
    

    use it to create and populate the 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);
    

    Since this is a Jackson type, Jackson knows how to serialize it.

    It doesn't know how to serialize JSONObject. Some of the following explanation comes from my answer here.

    Essentially, Spring MVC uses HandlerMethodReturnValueHandler implementations to handle values returned by @RequestMapping (@PostMapping) annotated methods. For ResponseEntity, that implementation is HttpEntityMethodProcessor.

    This implementation simply loops through a collection of HttpMessageConverter instances, checks if an instance can serialize the body of the ResponseEntity, and uses it if it can.

    Unfortunately, Jackson's HttpMessageConverter implementation, MappingJackson2HttpMessageConverter, uses an ObjectMapper to serialize these objects and ObjectMapper cannot serialize JSONObject because it can't discover any properties in the class (ie. bean getters).

    Jackson's HttpMessageConverter can't do it and neither can all the other ones that are registered by default. That's why Spring MVC reports "no converter".

    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
    

    An alternative solution is to serialize the JSONObject yourself to a String and pass that to the ResponseEntity. Obviously you'll want to change your return type to support String. In this case, Spring MVC will use a StringHttpMessageConverter. However, you'll want to specify the application/json content type yourself because it doesn't add it. For example,

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

提交回复
热议问题