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

2022-08-31 08:25:55

我在Spring Boot中有一个示例RestController:

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

我正在使用 JSON 库 org.json

当我点击API时,我得到一个异常说:/hello

Servlet.service() for servlet [dispatcherServlet] 在上下文中,路径 [] 抛出异常 [请求处理失败;嵌套异常是 java.lang.IllegalArgumentException: 找不到类型返回值的转换器:类 org.json.JSONObject] 具有根本原因

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

问题出在哪里?有人可以解释到底发生了什么吗?


答案 1

当您使用Spring Boot Web时,Jackson依赖性是隐式的,我们不必显式定义。如果使用 eclipse,您可以在依赖项层次结构选项卡中检查 Jackson 依赖项。pom.xml

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

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

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


答案 2

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

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

这将导致以下 JSON 响应:

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

这有点有限,因为添加子对象可能会变得更加困难。杰克逊有自己的机制,使用和。要使用它,您必须在服务/控制器中自动布线。然后,您可以使用:ObjectNodeArrayNodeObjectMapper

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

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