Jackson JSON
Spring MVC 对 Jackson JSON 库提供了深度集成,包括对 JSON 视图 (JSON Views) 的支持。
JSON 视图 (JSON Views)
JSON 视图允许你控制在序列化一个对象时渲染哪些字段。你可以通过 @JsonView 注解来激活一个特定的视图类。
使用示例
java
@RestController
public class UserController {
@GetMapping("/user")
@JsonView(User.WithoutPasswordView.class) // 激活“不含密码”的视图
public User getUser() {
return new User("eric", "7!jd#h23");
}
}
public class User {
public interface WithoutPasswordView {};
public interface WithPasswordView extends WithoutPasswordView {};
private String username;
private String password;
@JsonView(WithoutPasswordView.class)
public String getUsername() { return username; }
@JsonView(WithPasswordView.class)
public String getPassword() { return password; }
}kotlin
@RestController
class UserController {
@GetMapping("/user")
@JsonView(User.WithoutPasswordView::class)
fun getUser() = User("eric", "7!jd#h23")
}
class User(
@JsonView(WithoutPasswordView::class) val username: String,
@JsonView(WithPasswordView::class) val password: String) {
interface WithoutPasswordView
interface WithPasswordView : WithoutPasswordView
}编程式使用
如果你需要根据某些逻辑动态选择视图,可以使用 MappingJacksonValue:
java
@GetMapping("/user")
public MappingJacksonValue getUser() {
User user = new User("eric", "7!jd#h23");
MappingJacksonValue value = new MappingJacksonValue(user);
value.setSerializationView(User.WithoutPasswordView.class);
return value;
}补充教学
1. 为什么需要 JSON View?
- 场景一:隐私安全。在“用户列表”页,你只想给
username;但在“个人详情”页,你需要给email和phone。 - 场景二:性能优化。避免返回体积庞大的关联对象。
- 好处:你只需要维护一个 Domain/POJO 类,而不需要写一堆
UserListDTO、UserDetailDTO。
2. 字段排除的逻辑
Jackson 处理 @JsonView 时:
- 如果一个字段没有标注视图,默认情况下它会参与所有的序列化(除非你在 ObjectMapper 里关掉了这个开关)。
- 标注了视图的字段,只有在当前视图或其子接口被激活时才会被显示。
3. @JsonView 的限制
一个方法只能指定一个视图类。如果你想让一个接口同时满足两个视图,你需要定义一个综合接口:
java
public interface CombinedView extends ViewA, ViewB {}4. 配合 Boot 使用
在 Spring Boot 项目中,Jackson 几乎是零配置的。如果你想自定义日期格式或下划线命名,直接在 application.properties 里配置 spring.jackson.* 系列属性即可,非常方便。