序列化 之 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 为例)
- Controller 方法返回一个 Java 对象(如
User)。 - Spring MVC 查找合适的
HttpMessageConverter(根据Accept: application/json和返回类型)。 - 找到
MappingJackson2HttpMessageConverter。 - 调用其
write()方法,内部使用ObjectMapper.writeValue()将对象写入 HTTP 响应体。 - 客户端收到 JSON 数据。
反向流程(接收 JSON):
- 客户端发送 JSON 到服务端。
- Spring MVC 使用
@RequestBody注解标识参数。 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 |
| 中文乱码 | 确保 MappingJackson2HttpMessageConverter 的 supportedMediaTypes 包含 UTF-8(Spring Boot 默认已处理) |
总结
- Spring MVC 通过
MappingJackson2HttpMessageConverter集成 Jackson。 ObjectMapper是核心,可通过注解或全局配置定制行为。- Spring Boot 极大简化了配置,但仍需了解底层原理以应对复杂场景。
本文来自博客园,作者:蓝迷梦,转载请注明原文链接:https://www.cnblogs.com/hewei-blogs/articles/19522829

浙公网安备 33010602011771号