如何让杰克逊对同一类型的嵌套实体使用不同的视图?
How can I make jackson to use different views on nested entities of the same type?
在我开始提问之前,让我给你一个我的案例的简单例子:
假设你有 Views
:
public final class Views {
public interface Id { }
public interface IdText extends Id { }
public interface FullProfile extends IdText { }
}
您还有一个 class User
,它有相同类型的订阅者 User
。
id
和 username
属性在 Views.IdText.class
视图中序列化。并且 属性 subscribers
在 Views.FullProfile.class
视图中被序列化。
@Entity
public class User implements UserDetails {
@Id
@JsonView(Views.IdText.class)
private Long id;
@JsonView(Views.IdText.class)
private String username;
@JsonIdentityReference
@JsonIdentityInfo(
property = "id",
generator = ObjectIdGenerators.PropertyGenerator.class
)
@JsonView(Views.FullProfile.class)
private Set<User> subscribers = new HashSet<>();
}
还有一个控制器 (ProfileController
),它有一个名为 get
的方法,returns 一个用户的配置文件。
@RestController
public class ProfileController {
@GetMapping("{id}")
@JsonView(Views.FullProfile.class)
public User get(@PathVariable("id") User user) {
// ... some service methods that has the necessary logic.
return user;
}
}
如您所见,该方法在 Views.FullProfile.class
视图中序列化了用户的配置文件,因此输出为:
{
"id": 39,
"username": "ryan",
"subscribers": [
{
"id": 42,
"username": "elliott",
"subscribers": [
{
"id": 432,
"username": "oliver",
"subscribers": [
{
"id": 2525,
"username": "james",
"subscribers": [
39,
432
]
},
{
// ... a lot of useless data goes on.
}
]
},
{
"id": 94923,
"username": "lucas",
"subscribers": [
345, 42
]
}
]
},
{
"id": 345,
"username": "jocko",
"subscribers": [
94923
]
}
]
}
当用户的个人资料被序列化时,我不需要在 Views.FullProfile.class
视图中序列化用户的订阅者
但在 Views.IdText.class
视图中,输出将是:
{
"id": 39,
"username": "ryan",
"subscriptions": [
{
"id": 42,
"username": "elliott"
},
{
"id": 345,
"username": "jocko"
}
]
}
如何让 jackson 对同一类型的嵌套实体使用不同的视图?
或者我还需要做些什么才能做到这一点?
经过一段时间的不断搜索,我发现有人在 Github 上发布了同样的问题:@JsonIgnoreProperties
should support nested properties #2940
如该期所述:
No plans to ever implement this (due to delegating design, will not be possible with current Jackson architecture), closing.
在我开始提问之前,让我给你一个我的案例的简单例子:
假设你有 Views
:
public final class Views {
public interface Id { }
public interface IdText extends Id { }
public interface FullProfile extends IdText { }
}
您还有一个 class User
,它有相同类型的订阅者 User
。
id
和 username
属性在 Views.IdText.class
视图中序列化。并且 属性 subscribers
在 Views.FullProfile.class
视图中被序列化。
@Entity
public class User implements UserDetails {
@Id
@JsonView(Views.IdText.class)
private Long id;
@JsonView(Views.IdText.class)
private String username;
@JsonIdentityReference
@JsonIdentityInfo(
property = "id",
generator = ObjectIdGenerators.PropertyGenerator.class
)
@JsonView(Views.FullProfile.class)
private Set<User> subscribers = new HashSet<>();
}
还有一个控制器 (ProfileController
),它有一个名为 get
的方法,returns 一个用户的配置文件。
@RestController
public class ProfileController {
@GetMapping("{id}")
@JsonView(Views.FullProfile.class)
public User get(@PathVariable("id") User user) {
// ... some service methods that has the necessary logic.
return user;
}
}
如您所见,该方法在 Views.FullProfile.class
视图中序列化了用户的配置文件,因此输出为:
{
"id": 39,
"username": "ryan",
"subscribers": [
{
"id": 42,
"username": "elliott",
"subscribers": [
{
"id": 432,
"username": "oliver",
"subscribers": [
{
"id": 2525,
"username": "james",
"subscribers": [
39,
432
]
},
{
// ... a lot of useless data goes on.
}
]
},
{
"id": 94923,
"username": "lucas",
"subscribers": [
345, 42
]
}
]
},
{
"id": 345,
"username": "jocko",
"subscribers": [
94923
]
}
]
}
当用户的个人资料被序列化时,我不需要在 Views.FullProfile.class
视图中序列化用户的订阅者
但在 Views.IdText.class
视图中,输出将是:
{
"id": 39,
"username": "ryan",
"subscriptions": [
{
"id": 42,
"username": "elliott"
},
{
"id": 345,
"username": "jocko"
}
]
}
如何让 jackson 对同一类型的嵌套实体使用不同的视图? 或者我还需要做些什么才能做到这一点?
经过一段时间的不断搜索,我发现有人在 Github 上发布了同样的问题:@JsonIgnoreProperties
should support nested properties #2940
如该期所述:
No plans to ever implement this (due to delegating design, will not be possible with current Jackson architecture), closing.