如何解决如何根据场景使用@JsonView / @JsonBackReference / @JsonIdentityInfo序列化所需的子元素
考虑具有这样的DTO
@Data
class Profile {
@JsonView({Profile.Views.Simple.class,Views.AllFields.class})
String name;
@JsonView(Profile.Views.AllFields.class)
Collection<Image> images;
static class Views {
static class Simple {
}
static class AllFields {
}
}
}
@Data
@AllArgsConstructor
class Image {
@JsonView({Image.Views.Simple.class,Profile.Views.AllFields.class})
String name;
@JsonView(Image.Views.AllFields.class)
Profile profile;
static class Views {
static class Simple {
}
static class AllFields {
}
}
}
我可以想象一个非常简单的场景,根据操作的根是什么,我希望具有第一级相关对象的根实体的JSON输出。
获取用户
{
name: userName,images: [
{
name: image1Name
}
]
}
或在获取图像时
{
name: imageName,user: {
name: userName
}
}
是否可以使用某种@JsonView技巧,还是必须针对不同情况创建单独的DTO?
Jackson ObjectMapper似乎只能处理单个类视图,因此可以尝试
Profile p = new Profile();
p.setName("ProfileName");
p.setImages(Arrays.asList(new Image("ImageName1",p),new Image("ImageName",p)))
System.out.println(mapper
.writerWithView(Profile.Views.AllFields.class)
.withView(Image.Views.Simple.class)
.writeValueAsString(p));
System.out.println(mapper
.writerWithView(Profile.Views.Simple.class)
.withView(Image.Views.Simple.class)
.writeValueAsString(p.getImages().iterator().next()));
产生空的json。
解决方法
Jackson是一种魔术(当它以您想要的方式工作时)。
第一个问题是使用@JsonIdentityInfo
解决由于循环依赖性导致的无限递归。
第二个问题是在使用@JsonView
序列化各个bean时隐藏特定字段。
Profile.java
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,property = "name")
class Profile {
String name;
@JsonView(Views.Profile.class)
Collection<Image> images;
// setter getter or lombok annotations
}
Image.java
@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,property = "name")
class Image {
String name;
@JsonView(Views.Image.class)
Profile profile;
// constructor,setter getter or lombok annotations
}
Views.java
class Views {
public static class Profile {}
public static class Image {}
}
最后 Main.java
public static void main(String[] args) throws IOException {
Profile p1 = new Profile();
p1.setName("ProfileName1");
Profile p2 = new Profile();
p2.setName("ProfileName2");
Image image1 = new Image("ImageName1",p1);
Image image2 = new Image("ImageName2",p2);
p1.setImages(Arrays.asList(image1,image2));
String json = mapper
.writerWithView(Views.Profile.class)
.writeValueAsString(p1);
System.out.println(json);
json = mapper.
writerWithView(Views.Image.class)
.writeValueAsString(image1);
System.out.println(json);
}
Output:
// p1
{
"name": "ProfileName1","images": [
{
"name": "ImageName1"
},{
"name": "ImageName2"
}
]
}
// image1
{
"name": "ImageName1","profile": {
"name": "ProfileName1"
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。