侧边栏壁纸
  • 累计撰写 90 篇文章
  • 累计创建 95 个标签
  • 累计收到 10 条评论

目 录CONTENT

文章目录

Jackson常用的注解

汤圆学Java
2022-02-25 / 0 评论 / 0 点赞 / 119 阅读 / 4,969 字
温馨提示:
本文最后更新于 2022-02-25,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

前面介绍了Jackson序列化和反序列化相关的注解;

本篇再介绍几个比较常用的注解;

其实这里面的注解之前的文章也有提到过,只是在这里做个总结,为了方便;

目录

  1. @JsonProperty
  2. @JsonFormat
  3. @JsonUnwrapped
  4. @JsonView

正文

1. @JsonProperty

这个注解是用来将Json字符串中的属性名和Java类中的属性名对应起来;

功能上类似前面序列化和反序列化中介绍的@JsonGetter和@JsonSetter,可以认为这个注解是他俩的合体;

下面我们看个例子,实体类User如下:

@AllArgsConstructor
@NoArgsConstructor
@ToString
public class User {

    private String username;

    @JsonProperty(value = "name")
    public void setUsername(String name){
        this.username = name;        
    }

    @JsonProperty(value = "name")
    public String getUsername(){
        return this.username;
    }
    
}

假设Json字符串中的属性名为name,而这里的User类的属性名为username;

为了使他们在序列化和反序列化时,能够一一对应,这里我们在setter和getter方法上都加了@JsonProperty注解;

这样就可以给name和username建立一个映射关系;

下面是测试代码:

ObjectMapper objectMapper = new ObjectMapper();
User jalon = new User("jalon");
String s = objectMapper.writeValueAsString(jalon);
System.out.println(s);

输出为:{"name":"jalon"}

如果我们想要反序列化,也是可以的,代码如下:

User user = objectMapper.readValue(s, User.class);
System.out.println(user);

输出为:User(username=jalon)

可以看到,不管是序列化还是反序列化,@JsonProperty都可以完美的处理属性之间的映射关系;

2. @JsonFormat

这个注解在Jackson处理日期 - 掘金 (juejin.cn)中介绍过;

它主要是用来处理java.util.Date日期;

我们还是以上面的User为例,在它的基础上加一个birth属性,如下所示:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date birth;

然后测试代码中,构造User时多传入一个new Date()即可,如下所示:

ObjectMapper objectMapper = new ObjectMapper();
User jalon = new User("jalon", new Date());
String s = objectMapper.writeValueAsString(jalon);
System.out.println(s);

输出为:{"birth":"2022-02-22 09:16:48","name":"jalon"}

可以看到,birth属性确实按照我们设置的默认进行输出了,但是时间不准;

这是因为时区没有配置,重新修改birth属性,如下所示:

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birth;

此时输出正常:{"birth":"2022-02-22 17:20:37","name":"jalon"}

3. @JsonUnwrapped

当Java类属性有嵌套的对象时,可以用这个注解,将嵌套的对象平铺展开;

这里我们创建一个Animal类,然后将其添加到User类的属性中,如下所示:

@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {

    private String username;
    private Animal animal;

}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Animal{
    private String animalName;
}

这里我们先不加注解@JsonUnwrapped,看下是什么效果,测试代码如下:

ObjectMapper objectMapper = new ObjectMapper();
User jalon = new User("jalon",new Animal("tutu"));
String s = objectMapper.writeValueAsString(jalon);
System.out.println(s);

输出如下:

image-20220222173121341

可以看到,嵌套的Animal是以内置对象的方式进行展示;

为了直观显示,我们加上@JsonUnwrapped试试,加了注解的animal属性代码如下:

@JsonUnwrapped
private Animal animal;

再次运行,输出如下:

image-20220222173221946

可以看到,内置的animal被展开了,此时看起来会比较清晰明了;

此时反序列化还是可以组装回去的,即:

加了@JsonUnwrapped注解后:

  • 序列化可以对嵌套的对象进行展开处理;

  • 反序列化还可以对展开的对象进行折叠处理;

如果属性名有冲突怎么办呢?

有冲突也不影响序列化的正常输出,但是会影响反序列化的解析;

假设我们把他们的属性设置为一致,如下所示:

@Data
@AllArgsConstructor
@NoArgsConstructor
class Animal{
    private String username;
}

那么还是可以正常序列化,运行测试代码,结果如下:

image-20220222173647616

但是反序列化就会出问题,数据错乱,测试代码如下:

User user = objectMapper.readValue(s, User.class);
System.out.println(user);

结果如下:

image-20220222173744576

可以看到,结果乱了;

所以建议如果属性有重名的,不要用这个@JsonUnwrapped注解,以免造成数据混乱

4. @JsonView

这个注解类似前面介绍的Jackson如何隐藏字段 - 掘金 (juejin.cn),目的都是为了修改属性的可见性;

不过这个注解会比较麻烦一点,需要自己定义对应的类;

如下所示:我们定义一个View类,其中有Visible和Invisible两个内部类

public class View {
    public static class Visible{}
    public static class Invisible{}
}

然后在User类中进行配置:这里username属性加了View.Visible,而animal加了View.Invisble


@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {

    @JsonView(View.Visible.class)
    private String username;
    
    @JsonView(View.Invisible.class)
    private Animal animal;

}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Animal{
    private String animalName;
}

最后在测试代码的ObjectMapper中进行注册对应的View类,如下所示:

ObjectMapper objectMapper = new ObjectMapper();
User jalon = new User("jalon",new Animal("tutu"));
String s = objectMapper.writerWithView(View.Visible.class).writeValueAsString(jalon);
System.out.println(s);

此时运行输出如下:

image-20220222175056744

可以看到,animal被隐藏了,只输出了username属性;

总结

本篇介绍了几种常用的Jackson注解,包括:

  1. @JsonProperty: 用来解决属性名不匹配的情况
  2. @JsonFormat: 用来格式化 java.util.Date 日期
  3. @JsonUnwrapped: 用来展开/折叠嵌套的对象,
  4. @JsonView: 用来动态修改属性的可见性
0

评论区