我遇到从外部源接收到布尔值(字符串“ 0”或“ 1”)的情况。 映射时,Jackson不会对此进行娱乐,并引发以下错误:
InvalidFormatException:无法反序列化类型
boolean
的值 来自字符串“ 1”
因此,我正在按照有效的自定义反序列化进行操作。
在没有构建器的情况下的工作示例
@Getter
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
// many other fields
}
class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return "1".equals(parser.getText());
}
}
但是我需要它与构建器一起工作,并编写如下。这不再起作用。它引发与上述相同的错误。 有没有一种方法可以使构建器使用自定义反序列化功能?请注意,除非完全不可能,否则我将坚持使用Lombok的Builder。谢谢。
与构建器一起使用时的失败示例。 (我想对其进行修复以使其正常工作)
@Getter
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
// many other fields
}
class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return "1".equals(parser.getText());
}
}
快速测试用例,可以根据需要进行测试。
public class ATest {
@Test
public void myTest() throws IOException {
ObjectMapper mapper = new ObjectMapper();
// test passes if MyClass doesn't use builder.
MyClass myClass = mapper.readValue("{\"bool\":\"1\"}", MyClass.class);
assertTrue(myClass.isBool());
}
}
编辑:按照下面的答案尝试建议的选项
选项1:
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
// many other fields
@JsonSetter
private void setBool(String value){
this.bool = "1".equals(value);
}
}
class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {
@Override
public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return !"0".equals(parser.getText());
}
}
出现以下错误:
com.fasterxml.jackson.databind.JsonMappingException:问题 反序列化属性“ bool”(预期类型:[简单类型,类 java.lang.String];实际类型:
java.lang.Boolean
),问题: [来源:(String)“ {” bool“:” 1“}”处的参数类型不匹配;行:1 栏:9](通过参考链:a.a.a.MyClass [“ bool”])
选项2:
@Getter
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
private boolean bool;
}
出现以下错误:
com.fasterxml.jackson.databind.exc.InvalidFormatException:无法 从字符串“ 1”反序列化类型
boolean
的值:仅“ true”或 在[来源:(String)“ {” bool“:” 1“}”处识别为“ false”;行:1 栏:9](通过参考链: a.a.a.MyClass $ MyClassBuilder [“ bool”])
答案 0 :(得分:1)
更新2020-11-03:Lombok 1.18.16发布。
从Lombok 1.18.16开始,您可以使用@Jacksonized
自动生成Jackson使用Lombok @(Super)Builder
所需的一切:
@Getter
@Jacksonized
@Builder
public class MyClass {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
private boolean bool;
// many other fields
}
对于早期的Lombok版本,您必须自定义构建器,以便将注释添加到构建器的setter方法中。就您而言,它的工作方式如下:
@Getter
@Builder
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
public class MyClass {
private boolean bool;
// many other fields
public static class MyClassBuilder {
@JsonDeserialize(using = NumericBooleanDeserializer.class)
@JsonProperty("bool")
public MyClassBuilder bool(boolean bool) {
this.bool = bool;
return this;
}
}
}
Lombok认识到构建器已经存在一个类定义,并且仅为您未手动实现的方法生成代码。