avatar

jackson和lombok奇怪的序列化分析
  1. 问题

一个这样的类

1
2
3
4
5
6
7
8
9
10
11
12
package com.example.demo;

import lombok.Data;


@Data
public class AnyParams {
private String eValue;

private String target;

}

这里有两个属性,eValue,和target,但是eValue传入的参数,后端是接收不到的这是为什么呢?

然后我这么来测试

1
2
3
4
5
6
7
8
9
10
public static void main(String[] args) {

AnyParams anyParams = null;
try {
anyParams = new ObjectMapper().readValue("{\"eValue\" : \"1\",\"target\":\"1\"}", AnyParams.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
System.out.println(anyParams.toString());
}

结果如下

image-20240119201142077

这里的错误提示是说eValue没有值,但是上面明明是传了值的呀。

我们再换一种实现,这次我们的实体类用idea默认生成的get set方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.example.demo;



public class AnyParams {
private String eValue;

private String target;

public String geteValue() {
return eValue;
}

public void seteValue(String eValue) {
this.eValue = eValue;
}

public String getTarget() {
return target;
}

public void setTarget(String target) {
this.target = target;
}



@Override
public String toString() {
return "AnyParams{" +
"eValue='" + eValue + '\'' +
", target='" + target + '\'' +
'}';
}
}

这次我们看下结果

image-20240119201448973

这次就完全没有问题,那么应该就是lombok生成的get set有问题了,所以我们再看下lombok生成的java类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.example.demo;

public class AnyParams {
private String eValue;
private String target;

public AnyParams() {
}

public String getEValue() {
return this.eValue;
}

public String getTarget() {
return this.target;
}

public void setEValue(final String eValue) {
this.eValue = eValue;
}

public void setTarget(final String target) {
this.target = target;
}

public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof AnyParams)) {
return false;
} else {
AnyParams other = (AnyParams)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$eValue = this.getEValue();
Object other$eValue = other.getEValue();
if (this$eValue == null) {
if (other$eValue != null) {
return false;
}
} else if (!this$eValue.equals(other$eValue)) {
return false;
}

Object this$target = this.getTarget();
Object other$target = other.getTarget();
if (this$target == null) {
if (other$target != null) {
return false;
}
} else if (!this$target.equals(other$target)) {
return false;
}

return true;
}
}
}

protected boolean canEqual(final Object other) {
return other instanceof AnyParams;
}

public int hashCode() {
int PRIME = true;
int result = 1;
Object $eValue = this.getEValue();
result = result * 59 + ($eValue == null ? 43 : $eValue.hashCode());
Object $target = this.getTarget();
result = result * 59 + ($target == null ? 43 : $target.hashCode());
return result;
}

public String toString() {
return "AnyParams(eValue=" + this.getEValue() + ", target=" + this.getTarget() + ")";
}
}
  1. 问题研究

这次我们很容易看到和idea生成哪里不一样了吗,对对于单字母的驼峰命名eValue,idea默认第一个字母小写的,lombok是大写的。

我们看一下idea set的配置吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#set($paramName = $helper.getParamName($field, $project))
#if($field.modifierStatic)
static ##
#end
void set$StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))($field.type $paramName) {
#if ($field.name == $paramName)
#if (!$field.modifierStatic)
this.##
#else
$classname.##
#end
#end
$field.name = $paramName;
}

不太清楚这里的规则是吧。

我们用的Jackson,Jackson的序列化看起来应该是一样的规则,那我们来跟一下代码吧。

image-20240119202413182

image-20240119202528909

image-20240119202640937

image-20240119202804574

到这里我们比较关键的信息,这里找的信息已经变成了evalue了,

Jackson的序列化方式也是首字母为单字母的时候直接当小写处理了。

文章作者: 无知的小狼
文章链接: https://bytedance.press/2024/01/19/20240119/jackson%E5%92%8Clombok%E5%A5%87%E6%80%AA%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96%E5%88%86%E6%9E%90/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 无知的小狼

评论