- Jackson全面解析--注解全讲解七(@JsonGetter
- Jackson全面解析--注解全讲解八(@JsonIgnore,
- Jackson全面解析--注解全讲解二(@JsonAnyGett
- Jackson全面解析--注解全讲解一(@JacksonAnno
- Jackson全面解析--注解全讲解四(@JsonCreator
- Jackson全面解析--注解全讲解十一(@JsonProper
- Jackson全面解析--注解全讲解五(使用@JsonFilte
- Jackson全面解析--注解全讲解十二(动态添加字段@Json
- Jackson全面解析--注解全讲解九(过滤无用信息@JsonI
- Jackson全面解析--注解全讲解三(循环依赖杀手锏 @Jso
这一对注解用于序列化和反序列化,我们先看
@JsonGetter
先看个简单的例子,如下
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class Pojo{
@Getter
@Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
private String att1;
public String getTheAtt2(){
return "anyNull";
}
}
运行测试代码
@Test
public void JsonGetterTest() throws Exception{
CombineJacksonAnnotation.Pojo pojo = CombineJacksonAnnotation.Pojo.of("att1");
System.out.println(om.writeValueAsString(pojo));
}
结果如下
{
"att1" : "att1",
"theAtt2" : "anyNull"
}
可以看到
getTheAtt2()方法也被序列化了,按照驼峰命名规则去掉get剩下的就是默认的序列化之后的生成的属性名,而@JsonGetter的作用就是给这个被序列化的方法命名一个逻辑的属性名,如下,我们修改下代码
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class Pojo{
@Getter
@Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
private String att1;
@JsonGetter("att2")
public String getTheAtt2(){
return "anyNull";
}
}
再运行测试代码,返回如下
{
"att1" : "att1",
"att2" : "anyNull"
}
可以看到getTheAtt2()序列化后的属性名变成了att2,这就是@JsonGetter的作用。
我们可以继续的看下@JsonGetter的详细作用。
/**
* Marker annotation that can be used to define a non-static,
* no-argument value-returning (non-void) method to be used as a "getter"
* for a logical property.
* It can be used as an alternative to more general
* {@link JsonProperty} annotation (which is the recommended choice in
* general case).
*<p>
* Getter means that when serializing Object instance of class that has
* this method (possibly inherited from a super class), a call is made
* through the method, and return value will be serialized as value of
* the property.
*/
注释写的很清楚,用于一个无参的非静态的有一个返回值的方法,但是这个注解可以用@JsonProperty同样来实现,我们点到源码里面看下
JacksonAnnotationIntrospector.class
@Override
public PropertyName findNameForSerialization(Annotated a)
{
boolean useDefault = false;
JsonGetter jg = _findAnnotation(a, JsonGetter.class);
if (jg != null) {
String s = jg.value();
// 04-May-2018, tatu: Should allow for "nameless" `@JsonGetter` too
if (!s.isEmpty()) {
return PropertyName.construct(s);
}
useDefault = true;
}
JsonProperty pann = _findAnnotation(a, JsonProperty.class);
if (pann != null) {
return PropertyName.construct(pann.value());
}
if (useDefault || _hasOneOf(a, ANNOTATIONS_TO_INFER_SER)) {
return PropertyName.USE_DEFAULT;
}
return null;
}
可以看到@JsonGetter比@JsonProperty的优先级高,我们试验下,改下代码,如下
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class Pojo{
@Getter
@Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
private String att1;
@JsonGetter("att2")
@JsonProperty("att3")
public String getTheAtt2(){
return "anyNull";
}
}
返回结果没变
{
"att1" : "att1",
"att2" : "anyNull"
}
再次修改代码,如下
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class Pojo{
@Getter
@Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
private String att1;
@JsonProperty("att3")
public String getTheAtt2(){
return "anyNull";
}
}
返回结果变了
{
"att1" : "att1",
"att3" : "anyNull"
}
那如果我们修改成如下,如果方法序列化后的属性名与已存在的属性名重复会怎么样呢
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class Pojo{
@Getter
@Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
private String att1;
@JsonGetter("att1")
public String getTheAtt2(){
return "anyNull";
}
}
返回如下
{
"att1" : "anyNull"
}
上面的这点很重要,如果用的不好,可能发现序列化的结果不满足要求了。
@JsonSetter
既然@JsonGetter用于序列化,那么@JsonSetter就是用于反序列化了,
指定的method会去修改指定的属性。使用方法如下
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
class Pojo{
@Getter
@Setter //后面源码分析的时候要把这个地方看下,什么样的方法会被序列化
private String att1;
@JsonSetter(value = "att2")
public void setTheXxx(String xxx){
this.att1 = xxx;
}
}
上面的意思是说,解析出来的att2,然后将其值赋值给了att1,
image.png
所以反序列化出来就是上面的结果。
可以认为Jackson是按照标准的setter和getter来反序列化和序列化对象的,如果不是标准的方法,可以使用@JsonGetter @JsonSetter来转义。
网友评论