序列化 之 jackson(二)springmvc序列化

在 Spring MVC 中,Jackson 是默认的 JSON 序列化/反序列化库。它用于将 Java 对象转换为 JSON(序列化),以及将 JSON 转换回 Java 对象(反序列化)。Spring MVC 通过 HttpMessageConverter 接口集成 Jackson,其中核心实现是 MappingJackson2HttpMessageConverter


一、基本原理

1.1 核心组件关系

  • HttpMessageConverter:Spring 提供的接口,用于处理 HTTP 请求和响应中的消息体(如 JSON、XML 等)。
  • MappingJackson2HttpMessageConverter:基于 Jackson 的 ObjectMapper 实现的 JSON 消息转换器。
  • ObjectMapper:Jackson 的核心类,负责实际的序列化和反序列化操作。

1.2 工作流程(以返回 JSON 为例)

  1. Controller 方法返回一个 Java 对象(如 User)。
  2. Spring MVC 查找合适的 HttpMessageConverter(根据 Accept: application/json 和返回类型)。
  3. 找到 MappingJackson2HttpMessageConverter
  4. 调用其 write() 方法,内部使用 ObjectMapper.writeValue() 将对象写入 HTTP 响应体。
  5. 客户端收到 JSON 数据。

反向流程(接收 JSON):

  1. 客户端发送 JSON 到服务端。
  2. Spring MVC 使用 @RequestBody 注解标识参数。
  3. MappingJackson2HttpMessageConverter 调用 ObjectMapper.readValue() 将 JSON 转为 Java 对象。

二、依赖配置(Maven)

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.15.3</version> <!-- 或使用 Spring Boot 管理版本 -->
</dependency>

若使用 Spring Boot,通常已自动引入 spring-boot-starter-web,其中包含 Jackson。


三、基础使用示例

3.1 Controller 示例

@RestController
public class UserController {

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "张三", 25);
    }

    @PostMapping("/user")
    public ResponseEntity<String> createUser(@RequestBody User user) {
        // 处理 user 对象
        return ResponseEntity.ok("用户创建成功: " + user.getName());
    }
}

3.2 User 实体类

public class User {
    private Long id;
    private String name;
    private int age;

    // 构造函数、getter/setter 省略
    public User(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // getter/setter...
}

默认情况下,Jackson 会序列化所有 public 字段或带有 getter 的字段。


四、常用注解控制序列化行为

注解 作用
@JsonIgnore 忽略字段(序列化和反序列化)
@JsonProperty("custom_name") 自定义 JSON 字段名
@JsonFormat(pattern = "yyyy-MM-dd") 格式化日期
@JsonInclude(JsonInclude.Include.NON_NULL) 忽略 null 值字段
@JsonSetter / @JsonGetter 自定义 setter/getter 名称

示例:

public class User {
    private Long id;

    @JsonProperty("full_name")
    private String name;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthDate;

    @JsonIgnore
    private String password;

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private String description;

    // ...
}

五、全局配置 ObjectMapper(Spring Boot 方式)

application.yml 中:

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    serialization:
      write-null-map-values: false
      indent-output: true
    default-property-inclusion: non_null

或通过 Java 配置:

@Configuration
public class JacksonConfig {

    @Bean
    @Primary
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        mapper.registerModule(new JavaTimeModule()); // 支持 LocalDateTime 等
        return mapper;
    }
}

注意:Spring Boot 2.x+ 默认已注册 JavaTimeModule,但显式注册更安全。


六、自定义 HttpMessageConverter(高级)

若需完全控制 JSON 行为,可替换默认的 MappingJackson2HttpMessageConverter

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(customObjectMapper());
        converters.add(converter);
    }

    private ObjectMapper customObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        // 自定义配置...
        return mapper;
    }
}

注意:使用 @EnableWebMvc 会禁用 Spring Boot 的自动配置,慎用。


七、常见问题与解决方案

问题 解决方案
返回 LocalDateTime 变成时间戳 配置 WRITE_DATES_AS_TIMESTAMPS = false 并注册 JavaTimeModule
字段为 null 仍出现在 JSON 中 设置 @JsonInclude(Include.NON_NULL) 或全局配置
无法反序列化 JSON 到 POJO 检查是否有无参构造函数、setter 方法,或使用 @JsonCreator
中文乱码 确保 MappingJackson2HttpMessageConvertersupportedMediaTypes 包含 UTF-8(Spring Boot 默认已处理)

总结

  • Spring MVC 通过 MappingJackson2HttpMessageConverter 集成 Jackson。
  • ObjectMapper 是核心,可通过注解或全局配置定制行为。
  • Spring Boot 极大简化了配置,但仍需了解底层原理以应对复杂场景。
posted @ 2026-01-23 16:02  蓝迷梦  阅读(4)  评论(0)    收藏  举报