说在前边
这个问题发生在接口联调的时候,本地在idea测试没有问题,但是发到测试环境使用postman进行测试就出问题,做一个记录防止再犯,也希望可以帮助到其他的同志们。
现象
用postman请求接口时报出了序列化异常,错误信息很长基本上都是乱码,这里就不贴出来了,提示关键信息,no Creators, like default construct, exist。主要原因是因为请求接口的入参对象没有默认构造函数导致,可以看下你的是否是这样的原因呢?那么为什么会导致这样的结果呢,我们继续一步一步往下走,入参的实体对象使用了@Data和@Builder进行注解。
@Data
@Builder
public class TestBuilder {
private String name;
private Integer age;
public void start() {
System.out.println("这是开始");
}
public void end() {
System.out.println("这是结束");
}
}
经常使用lombok的同志们都知道,@Data已经包含了构造函数和set、get、equals、hashCode、canEqual、和toString,这个可以从字节码文件中看出来,如下图
但是为什么和@Builder一起使用后则默认的无参构造没有呢,我们看下增加了@Builder后的字节码信息
可以看到增加了一个带参的构造函数和一个builder()方法,在target目录下找到实体类的class文件,文件中并没有一处实现了该实体了的无参构造函数,这里贴关键代码,其中会有这样的两段代码
- builder()方法
public static TestBuilderBuilder builder() {
return new TestBuilderBuilder();
}
2.静态内部类
public static class TestBuilderBuilder {
private String name;
private Integer age;
TestBuilderBuilder() {
}
public TestBuilderBuilder name(final String name) {
this.name = name;
return this;
}
public TestBuilderBuilder age(final Integer age) {
this.age = age;
return this;
}
public TestBuilder build() {
return new TestBuilder(this.name, this.age);
}
public String toString() {
return "TestBuilder.TestBuilderBuilder(name=" + this.name + ", age=" + this.age + ")";
}
}
可以看到在静态内部类中build()方法直接创建了一个全部参数的构造,所以在@Data和@Builder同时使用时会出现无参构造不存在的现象。那么该如何解决这一问题呢?
解决方法
有其他的同志们给出的解决方法有增加构造函数,或者使用@Tolerate注解,这里解释一下@Tolerate这个注解是做什么的,引用官方文档的描述:放置任何方法或构造函数以使 lombok 假装它不存在,即生成一个方法,否则该方法会由于可能的冲突而被跳过。lombok官方API文档:https://projectlombok.org/api/。话说回来,我们看下两种解决方式有什么不同的
第一种,增加@NoArgsConstructor@AllArgsConstructor 两个注解
很直白,从字节码文件中可以看出这两个注解会帮助我们直接生成两个构造函数,如图
第二种,写一个无参构造增加@Tolerate注解
这里只是又帮我们增加了一个无参构造
两者并没有很大的区别,使用哪种全看同志们自己的选择,可以根据一些情况来判断,比如说需要在构造函数中进行一些初始化数据操作,那么就可以采用第二种。
结束在后边
今天的分享到这里结束了,希望可以让其他同志们采坑。
再次声明,以上内容仅是笔者个人理解绝无抄袭他人,有理解不当之处还请同志们多多指点,互相交流