当前位置: 首页 > 知识库问答 >
问题:

使用构建器时无法执行自定义反序列化

赵雅懿
2023-03-14

我遇到过这样的情况:我从外部源接收到字符串“0”或“1”形式的布尔值。在映射时,杰克逊不考虑这一点,并抛出以下错误:

无效格式异常:无法从字符串“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());
    }
}

但是我需要这个来与构建器一起工作,并按如下方式编写。这不再有效。它抛出与上述相同的错误。有没有办法让构建者使用自定义反序列化来解决这个问题?请注意,我想坚持使用龙目岛的建造者,除非它根本不可能。谢谢。

失败的例子,当与一个建设者。(我想修复它以使其正常工作)

@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.Json映射异常: 反序列化属性“布尔”(预期类型:[简单类型,类 java.lang.字符串];实际类型: java.lang.布尔), 问题: 参数类型不匹配在 [来源: (字符串) “{”bool“:”1“}”; 行: 1, 列: 9] (通过引用链: a.a.a.MyClass[“布尔”])

选项2:

@Getter
@JsonDeserialize(builder = MyClass.MyClassBuilder.class)
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class MyClass {

    @JsonDeserialize(using = NumericBooleanDeserializer.class)
    @JsonProperty("bool")
    private boolean bool;
}

获取以下错误:

无效格式异常:无法从字符串“1”反序列化布尔类型的值:只有“真”或“假”识别[来源:(字符串)“{”布尔“:”1“}”;行:1,列:9](通过参考链:a.a.a.MyClass$MyClassBuilder[“布尔”])

共有1个答案

东门令
2023-03-14

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认识到构建器已经有一个类定义,并且只为您没有手动实现的方法生成代码。

 类似资料:
  • 问题内容: 我有一堂课 我想将下面的JSON数据反序列化到上面的类/对象中 我的想法是在JSON中是一个对象,但我只想获取(在JSON中)在反序列化期间将像在类中那样传递。 如何使用Json.NET实现该目标? 我相信我可以使用CustomJsonConverter完成它。但是我很困惑。docs中的示例仅用于,但不适用。 问题答案: 我只是使用上面在问题中提到的方法解决了我的问题。在我完整的代码下

  • 问题内容: 我在使用Gson解析JSON响应时遇到问题。 JSON字串: 我有这两个课程: 但是当使用Gson解析这个时我有一个异常。我知道这是因为响应数组的第一个元素不是对象,而是整数。 所以问题是,我能以某种方式解决它吗? 问题答案: 您必须编写一个 自定义反序列化器 。我会做这样的事情: 首先,您需要包括一个新的类,而不是已有的两个类: 然后,您需要一个自定义解串器,类似于以下内容: 然后,

  • 我想通过扩展默认的反序列化器来创建自己的反序列化器,在其后面设置更多的值: 如您所见,我还想将此DTO母类重用于其他DTO。 我没有找到任何这样的例子。我真的是世界上第一个 反序列化的“AsUsual”(p,ctxt)应该是什么 我应该使用什么motherclass?JsonDeserializer/StdDeserializer/UntypedObjectDeserializer 反序列化程序会

  • 我正在尝试为泛型列表创建一个自定义反序列化器。假设我得到了类B的json表示: 其中A是我仅在运行时看到的其他类。我想创建一个反序列化程序,该程序能够将listObject的类型推断为具有内部类型a的list,并将其反序列化,而不是使用默认的hashmap反序列化程序。 我尝试使用上下文反序列化器,类似于这里建议的,然后将其添加为List的自定义反序列化器 但是我不确定我应该如何读取json并在反

  • 我有一个JestClient(elasticsearch)响应,我试图将其反序列化为一个对象。该对象包含两个DateTime字段,而在响应中,它们是字符串,因此我得到: 所以,我创建了一个自定义反序列化器来解决这个问题…然而,无论我做什么,我总是得到同样的错误。不知何故它没有注册使用它? 最后,我试图解析JestClient响应的代码: 无论我尝试什么,我总是得到上面的错误,我甚至不确定在这一点上

  • 问题内容: 我正在使用Flickr API 。调用该方法时,默认的JSON结果为: 我想将此响应解析为Java对象: JSON属性应按以下方式映射: 不幸的是,我无法找到一种使用Annotations做到这一点的好方法。到目前为止,我的方法是将JSON字符串读入a 并从中获取值。 但是我认为,这是有史以来最不优雅的方式。有没有简单的方法,可以使用注释还是自定义反序列化器? 这对我来说将是很明显的,