lombok getter、setter 特殊属性转换问题
概述
在生产中遇到一个json转化的问题,发现接口的属性传输正确,但是程序却填充不进类的属性里面,值为null;因为生产的原因,我另外写了个demo,不会涉密。具体情况大致如下:
代码
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class TestModel {
private String abc;
private String eFg;
private String hIJ;
private String KLMN;
private String myModel;
}
@PostMapping("/testLombok")
public String testLombok(@RequestBody TestModel testModel) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
String jsonStr = mapper.writeValueAsString(testModel);
log.info("[testLombok]jsonStr:{}", jsonStr);
TestModel testModel1 = mapper.readValue(jsonStr, TestModel.class);
log.info("[testLombok]toString:{}", testModel1.toString());
return testModel1.toString();
}
postman传参调用
预想结果
感觉应该能正常接收,正常跑下去
事实的结果
为什么会这样,究竟发生了啥,不符合正常逻辑呀,我们下面来探究探究,什么是快乐星球
我们继续跑下去,看看打印的日志
你会发现,这序列化的json属性不对呀
那来个逆向的思路,把这个看上去不对的json字符串传参进去,看看能不能正常接收
逆向
开始请求
居然传进来了,但是不是我定义的属性名呀
解决
怎么回事,超出了我的认知范围,这是个bug吗?
其实要解决属性问题可以用jackson的@JsonProperty注解去解决,但是这次的问题是探究为啥会出现上述的情况,贴一下解决办法先
解决办法一
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.ToString;
@Data
@ToString
public class TestModel {
private String abc;
@JsonProperty("eFg")
private String eFg;
@JsonProperty("hIJ")
private String hIJ;
@JsonProperty("KLMN")
private String KLMN;
private String myModel;
}
解决办法二
TestModel 类去掉@Data
手写或idea自动生成属性的getter、setter
注意:KLMN这个全大写的属性比较特殊,用@JsonProperty("KLMN")
解决完了
原因
下面探究下为什么会出现文中的情况,疯狂google,百度中。。。。。。
根本原因:lombok的@Data和spring的jackson对于getter和setter的生成方式不一样照成的
究竟谁对谁错
lombok官方的解释是这样的
JavaBeans的规范就是这样的,Lombok只是遵循这个规范⽽已,并且不应该使⽤⾸字母⼩写,第⼆个字母⼤写这样的
命名规则,⽽Spring的处理⽅式才是没有遵循JavaBean的规范。除⾮Oracle官⽅推荐如此或者⼤家都是这样处理的
化,Lombok才会进⾏修改
其实JavaBeans并没有严格规定首字母小写,第二个字母大写的情况,嗯,lombok也没错,spring也没错,只是实现的方式不同
总结
- 遇到相应的问题,比如属性转换不了,属性名不对,可以使用json属性别名等注解,如jackson用@JsonProperty,fastjson用@JSONField
- 尽量避免非正规或者有歧义的变量书写,如上述的首字母小写第二字母大写、首字母大写等变量名称,明知有歧义的话就要尽量避免,免得有奇怪的bug,命名要符合java驼峰写法
遇事总结记录,往事回首,经验已逐渐丰富,大家加油