【发布时间】:2020-04-25 00:01:27
【问题描述】:
我有一种情况,我从外部源接收一个布尔值作为字符串“0”或“1”。 映射时,杰克逊不接受这一点并抛出以下错误:
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),问题: [Source: (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类型的值:仅“真”或 “假”在 [Source: (String)"{"bool":"1"}";线:1, 栏:9](通过参考链: a.a.a.MyClass$MyClassBuilder["bool"])
【问题讨论】: