【问题标题】:JsonDeserialize set inherited properties also when objectmapper readvalueJsonDeserialize 在 objectmapper 读取值时也设置继承的属性
【发布时间】:2020-02-19 07:18:09
【问题描述】:

当 objectmapper 读取继承属性的值时,JsonDeserialize 不起作用。

车辆类别

@Getter
@Setter
@JsonDeserialize(builder = Vehicle.VehicleBuilder.class)
@Builder(builderClassName = "VehicleBuilder", toBuilder = true)
public class Vehicle{
    private String name;
    private String noOfTyres;
    @JsonPOJOBuilder(withPrefix = "")
    public static class VehicleBuilder{
    }
}

汽车类

@Getter
@Setter
@JsonDeserialize(builder = Car.CarBuilder.class)
@Builder(builderClassName = "CarBuilder", toBuilder = true)
public class Car extends Vehicle {
    private String carType;

    @JsonPOJOBuilder(withPrefix = "")
    public static class CarBuilder extends VehicleBuilder {
    }
}

我不想在两个类中都创建@NoArgsConstructor ,@AllArgsConstructor。 我在Car car = om.readValue(jsonValue,Car.class); 时的问题 当我将 Json 解析为 java 对象时,父类属性设置不正确。

到目前为止,我正在使用 @NoArgsConstructor ,@AllArgsConstructor 来解决用例问题。

有什么办法可以和@JsonDeserialize and @JsonPOJOBuilder一起使用吗?

【问题讨论】:

    标签: java json builder json-deserialization


    【解决方案1】:

    代码的问题在于它假定继承类中的构建器也会设置父属性。不幸的是,他们并没有开箱即用。但是,这可以通过 Lombok 实现,但需要一些额外的代码,如 post 中所述。

    完整的解决方案如下所示。

    父类

    @Getter
    @Setter
    @JsonDeserialize
    @Builder(builderClassName = "VehicleBuilder", builderMethodName = "vehicleBuilder")
    public class Vehicle {
        private String name;
        private String noOfTyres;
    
    }
    

    儿童班

    @Getter
    @Setter
    @JsonDeserialize(builder = Car.CarBuilder.class)
    public class Car extends Vehicle {
    
        private String carType;
    
        @Builder
        public Car(String name, String noOfTyres, String carType) {
            super(name, noOfTyres);
            this.carType = carType;
        }
    
        @JsonPOJOBuilder(withPrefix = "")
        public static class CarBuilder extends VehicleBuilder {
        }
    
    }
    

    请注意,扩展类的构建器是通过提供带有 @Builder 注释的构造器来实现的。另请注意,扩展类未设置注释参数 toBuilder=true,因为这将需要访问私有的父属性。这可以通过将父类属性设置为受保护来实现。

    【讨论】:

    • 实际上我在子类中有很多属性。这样 Builder public Car(String name, String noOfTyres, String carType) { super(name, noOfTyres); this.carType = carType; } 在我的用例中是不可能的。
    • 为什么不可能?您可以扩展构造函数以包含它们。没错,这是添加样板代码,但我猜仍然比编写自己的构建器要好。如果您查看链接的帖子,您可以使用 @SuperBuilder 以防您使用 Lombok 1.18 及更高版本来避免构造函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-17
    • 1970-01-01
    • 2019-03-09
    • 2013-06-25
    • 1970-01-01
    • 2013-01-05
    相关资源
    最近更新 更多