1. 问题所示
执行脱敏函数的时候,出现如下问题:
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Class com.example.test.ChineseNameDesensitization$Serializer has no default (no arg) constructor
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:77)
at com.fasterxml.jackson.databind.SerializerProvider.reportBadDefinition(SerializerProvider.java:1300)
at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:1447)
at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:544)
at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:822)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:308)
at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4568)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3821)
at com.example.test.test.main(test.java:82)
截图如下所示:
2. 原理分析
本着问题导向的分析,分析Bug的提示词
异常是由于Jackson库在序列化对象时发现了一个问题
InvalidDefinitionException
: Jackson库的一个异常类,用于指示在序列化或反序列化期间发现的问题。Class com.example.test.ChineseNameDesensitization$Serializer has no default (no arg) constructor
: 异常消息指出问题所在,Jackson要求自定义的序列化器类必须有一个默认的(无参的)
构造函数
解决方式有如下:
- 添加默认构造函数: 在
ChineseNameDesensitization$Serializer
类中添加一个无参的构造函数即可
public class Serializer {
public Serializer() {
// 默认构造函数
}
// 其他代码
}
- 使用内部静态类: 如果Serializer类是作为ChineseNameDesensitization类的内部静态类实现的,确保它是静态的
public class ChineseNameDesensitization {
// 其他代码
public static class Serializer {
// 构造函数和其他代码
}
}
- 使用@JsonSerialize注解: 如果Serializer类是用于特定字段或方法的自定义序列化器,可以考虑使用
@JsonSerialize
注解来指定它,将其与字段或方法相关联,并且不需要显示地在类中声明默认构造函数
@JsonSerialize(using = ChineseNameDesensitization.Serializer.class)
public class MyClass {
// 字段和其他代码
}
选择哪种方法取决于代码结构和需求
3. 解决方法
本次采用无参构造函数的融入
// 脱敏处理器
class ChineseNameDesensitization {
public static class Serializer extends JsonSerializer<String> {
private int prefixKeep;
private int suffixKeep;
private String replacer;
// 默认构造函数
public Serializer() {
// 这里可以设置默认的参数值,或者留空
}
// 带参数的构造函数
public Serializer(int prefixKeep, int suffixKeep, String replacer) {
this.prefixKeep = prefixKeep;
this.suffixKeep = suffixKeep;
this.replacer = replacer;
}
// 其他方法
最终截图如下: