【问题标题】:How JSON body is converted to POJO in Spring MVCSpring MVC 中 JSON 正文如何转换为 POJO
【发布时间】:2018-04-21 23:33:24
【问题描述】:

我有课

class Student {
    String id;
    String name;
    //getters
    //setters
}

我有一个 JSON 请求

{
  "id": "1",
  "name": "asd",
}

我有一个 REST API

@RequestMapping(value = "/student", method = RequestMethod.POST, produces = "application/json")
    public @ResponseBody String getstudent(HttpServletRequest request, HttpServletResponse response,
            @RequestBody Student student,
            @RequestHeader HttpHeaders requestHeaders) {

     return null;
}

当我调用这个 API 并可视化这个 student 对象时,这两个字段都有我提供的请求中的值。

我不明白的是:

  1. JSON 值如何直接映射到 Student 类对象?
  2. 是否涉及序列化/反序列化?
  3. 学生班有没有构造函数的重要性?

【问题讨论】:

    标签: java rest serialization deserialization


    【解决方案1】:

    1) JSON 值如何直接映射到 Student 类对象:

    您使用的 Web 应用程序配置了 Spring MVC 支持(配置了 @EnableWebMvc@Configuration 等)。

    默认启用了一些HttpMessageConverters

    收到一个新的请求,Spring 使用Accept header 来确定媒体类型。然后它找到可以处理媒体类型的注册转换器。它将使用它来转换实体并发回响应。接收带有 JSON 信息的请求 - Spring 使用 Content-Type 标头来确定请求正文的媒体类型。

    然后它将搜索一个HttpMessageConverter,可以将客户端发送的正文转换为Java对象。

    例如 MappingJackson2HttpMessageConverter 是 JSON 转换器之一:

    公共类 MappingJackson2HttpMessageConverter 扩展 AbstractJackson2HttpMessageConverter 的实现 可以使用 Jackson 2.x 读写 JSON 的 HttpMessageConverter 对象映射器。此转换器可用于绑定到类型化的 bean,或 无类型的 HashMap 实例。

    默认情况下,此转换器支持 application/json 和 application/*+json 带有 UTF-8 字符集。这可以被覆盖 设置supportedMediaTypes 属性。

    默认构造函数使用由提供的默认配置 Jackson2ObjectMapperBuilder。

    从 Spring 5.0 起与 Jackson 2.9 及更高版本兼容。

    @RequestBody 用于参数告诉 Spring 应该将 HTTP 请求反序列化为 Java 实体。客户端应用程序指定的Content-Type 标头将有助于确定合适的转换器。

    @ResponseBody 在方法上向 Spring 指示返回值直接序列化到 HTTP 响应的主体。

    2) 是否涉及序列化/反序列化?

    直接涉及序列化和反序列化。

    公共字段,带有提供 getter 的字段是可序列化和可反序列化的。 setter 使非公共字段仅可反序列化。 全局配置也可以在 ObjectMapper 级别完成,以使用公共字段或 getter/setter 方法进行序列化。

    3) 构造函数在学生课中是否重要?

    默认情况下不涉及构造函数。正如我在上一节中提到的,getter 和 setter 用于访问字段。

    但是可以使用@JsonCreator@JsonProperty配置构造函数来参与序列化/反序列化过程:

    @JsonCreator
    public Student (@JsonProperty("id") String id, @JsonProperty("name") String name) {
        this.id = id;
        this.name = name;
    }
    

    【讨论】:

    • 谢谢你的详细解释,帮了我很多,你能帮我解决一下构造函数和setter调用的顺序吗
    • 你的意思是什么顺序?杰克逊叫来的?
    • 附带说明,在大多数现代应用程序中,您使用的是 Jackson 2 转换器。
    • @chrylis,说得好。我用 Spring 5 javadoc 更新了答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    • 2023-02-23
    • 2020-09-17
    • 1970-01-01
    相关资源
    最近更新 更多