Skip to content

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;但在“个人详情”页,你需要给 emailphone
  • 场景二:性能优化。避免返回体积庞大的关联对象。
  • 好处:你只需要维护一个 Domain/POJO 类,而不需要写一堆 UserListDTOUserDetailDTO

2. 字段排除的逻辑

Jackson 处理 @JsonView 时:

  1. 如果一个字段没有标注视图,默认情况下它会参与所有的序列化(除非你在 ObjectMapper 里关掉了这个开关)。
  2. 标注了视图的字段,只有在当前视图或其子接口被激活时才会被显示。

3. @JsonView 的限制

一个方法只能指定一个视图类。如果你想让一个接口同时满足两个视图,你需要定义一个综合接口:

java
public interface CombinedView extends ViewA, ViewB {}

4. 配合 Boot 使用

在 Spring Boot 项目中,Jackson 几乎是零配置的。如果你想自定义日期格式或下划线命名,直接在 application.properties 里配置 spring.jackson.* 系列属性即可,非常方便。

Based on Spring Framework.