前言
Jackson中注释有很多,这里我们先介绍部分跟序列化有关的,其他的后面再陆续介绍;
目录
- @JsonGetter
- @JsonValue
- @JsonSerialize
正文
1. @JsonGetter
该注解用在方法上,目的是替换已有的getter方法;
比如我有一个User类,如下所示:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String username;
private String nickname;
}
这里默认的getter都是通过@Data注解自动添加的;
此时如果我们想要用其他的方法覆盖默认的getUsername方法,就可以用@JsonGetter来实现,代码如下:
@JsonGetter(value = "username")
public String getMyName(){
return "actual name";
}
这里注解的值value='username'
,表示username的getter
方法会被这里的方法覆盖(默认的getter会失效);
用下面的代码可以进行测试:
ObjectMapper objectMapper = new ObjectMapper();
User user = new User("jalon", "test");
String s = objectMapper.writeValueAsString(user);
System.out.println(s);
运行后,输出如下:
可以看到,输出的并不是构造时的数据,而是@JsonGetter注解的方法所返回的数据;
这个注解@JsonGetter改变的只是序列化的值,如果我们直接通过
user.getUsername()
来获取,返回的还会是构造时的数据jalon
2. @JsonValue
@JsonValue的目的是为了序列化整个实例;
如果用了@JsonValue注解,那么序列化时只会从@JsonValue注解的方法上执行,不再去执行其他的序列化;
比如,我们将@JsonValue注解在getUsername()方法上,如下所示;此时Jackson只会序列化username属性,其他的属性比如nickname不会被序列化;
@JsonValue
public String getUsername(){
return username;
}
测试代码如下:
ObjectMapper objectMapper = new ObjectMapper();
User user = new User("jalon", "test");
String s = objectMapper.writeValueAsString(user);
System.out.println(s);
输出如下:
可以看到,输出只有一个username属性,这是因为Jackson此时只去@JsonValue下面进行了序列化,其他的getter方法没进行序列化
注:此时反序列化是无法成功的,因为我们已经修改了序列化的结构;反序列化可参考@JsonCreator
不过常用的做法是将@JsonValue用在toString方法上,用来覆盖默认的转换行为,如下所示:
@JsonValue
@Override
public String toString() {
return "User-@JsonValue{" +
"username='" + username + '\'' +
", nickname='" + nickname + '\'' +
'}';
}
此时运行输出,就会看到完整的数据了,如下所示:
3. @JsonSerialize
这个注解之前接触过,主要用来序列化日期;
我们重新定义一个User类,包含一个生日,如下所示:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String username;
private Date birth;
@JsonSerialize(using = CustomDateSerializer.class)
public Date getBirth(){
return birth;
}
}
这里我们将@JsonSerialize注解加在getBirth方法上,此时序列化birth时就会触发该注解,然后将日期进行对应的处理;
其中CustomDateSerializer.class
是我们自定义的日期序列化类,如下所示:
public class CustomDateSerializer extends StdSerializer<Date> {
private static SimpleDateFormat formatter
= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public CustomDateSerializer() {
this(null);
}
public CustomDateSerializer(Class<Date> t) {
super(t);
}
@Override
public void serialize(
Date value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
gen.writeString(formatter.format(value));
}
}
然后我们构造一个user对象,进行测试:
ObjectMapper objectMapper = new ObjectMapper();
User user = new User("jalon", new Date());
String s = objectMapper.writeValueAsString(user);
System.out.println(s);
输出如下:
可以看到,日期被成功格式化;
总结
本篇介绍了三个序列化会用到的注解:
- @JsonGetter:覆盖已有的getter方法
- @JsonValue:序列化整个实例,多用来覆盖toString()方法
- @JsonSerialize:多用来序列化日期
评论区