在Spring Boot中返回JSON对象作为响应

我在Spring启动时有一个示例Rest Controller:

@RestController @RequestMapping("/api") class MyRestController { @GetMapping(path = "/hello") public JSONObject sayHello() { return new JSONObject("{'aa':'bb'}"); } } 

我正在使用json库:org.json

当我点击api /你好时,我得到一个exception说:

servlet [dispatcherServlet]的Servlet.service()与path []的上下文引发了exception[请求处理失败; 嵌套exception是java.lang.IllegalArgumentException:没有为根本原因找到类型为:class org.json.JSONObject的返回值的转换器

java.lang.IllegalArgumentException:找不到类型为:class org.json.JSONObject的返回值的转换器

问题是什么 有人可以解释究竟发生了什么。 我是SpringBoot的新手。

提前致谢 :)

当您使用spring boot web时,jackson依赖是隐式的,我们不必明确定义。 如果使用eclipse,您可以在依赖关系层次结构选项卡中检查pom.xml中的jackson依赖项。

因为你已经注释了@RestController所以不需要进行显式的json转换。 只需返回一个POJO,jackson序列化器将负责转换为json。 它与@Controller一起使用时相当于使用@ResponseBody 。 我们不是将@ResponseBody放在每个控制器方法上,而是将@RestController而不是vanilla @Controller@ResponseBody默认应用于该控制器中的所有资源。
请参考此链接: https //docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-responsebody

您遇到的问题是因为返回的对象(JSONObject)没有某些属性的getter。 并且您的目的不是序列化此JSONObject,而是序列化POJO。 所以只需返回POJO。
请参阅此链接: https //stackoverflow.com/a/35822500/5039001

如果要返回json序列化字符串,则只返回字符串。 在这种情况下,Spring将使用StringHttpMessageConverter而不是JSON转换器。

您可以按照@vagaasen的建议将响应返回为String ,也可以使用Spring提供的ResponseEntity Object,如下所示。 通过这种方式,您还可以返回Http status code ,这在webservice调用中更有帮助。

 @RestController @RequestMapping("/api") public class MyRestController { @GetMapping(path = "/hello", produces=MediaType.APPLICATION_JSON_VALUE) public ResponseEntity sayHello() { //Get data from service layer into entityList. List entities = new ArrayList(); for (Entity n : entityList) { JSONObject entity = new JSONObject(); entity.put("aa", "bb"); entities.add(entity); } return new ResponseEntity(entities, HttpStatus.OK); } } 

您当前方法不起作用的原因是因为默认情况下使用Jackson来序列化和反序列化对象。 但是,它不知道如何序列化JSONObject 。 如果要创建动态JSON结构,可以使用Map ,例如:

 @GetMapping public Map sayHello() { HashMap map = new HashMap<>(); map.put("key", "value"); map.put("foo", "bar"); map.put("aa", "bb"); return map; } 

这将导致以下JSON响应:

 { "key": "value", "foo": "bar", "aa": "bb" } 

这有点受限,因为添加子对象可能会变得有点困难。 jackson有自己的机制,使用ObjectNodeArrayNode 。 要使用它,您必须在服务/控制器中自动assemblyObjectMapper 。 然后你可以使用:

 @GetMapping public ObjectNode sayHello() { ObjectNode objectNode = mapper.createObjectNode(); objectNode.put("key", "value"); objectNode.put("foo", "bar"); objectNode.put("number", 42); return objectNode; } 

此方法允许您添加子对象,数组和使用所有各种类型。

你也可以使用哈希映射

 @GetMapping public HashMap get() { HashMap map = new HashMap<>(); map.put("key1", "value1"); map.put("results", somePOJO); return map; } 
 @RequestMapping("/api/status") public Map doSomething() { return Collections.singletonMap("status", myService.doSomething()); } 

PS。 仅适用于1个值