java Lombok岛,Jackson化;从json构造核心类时如何创建自定义类对象

92dk7w1h  于 2023-03-21  发布在  Java
关注(0)|答案(1)|浏览(71)

我有三门课,第一:除了其他属性之外,“ItemProduct”具有两个基于类的字段。类“Reservation”和类“Something”。“ItemProduct”和“Reservation”是基于来自API的json响应的模型类。类“Something”使用来自ItemProduct和Reservation的数据生成,并且稍后用于其他操作。
代码:

@Data
@Builder
@Jacksonized
public class ItemProduct {
    @NotNull
    Integer id;
    @NotNull
    String status;
    @NotNull
    String productType;
    String productNo;
    @NotNull
    Reservation reservation;
    @JsonIgnore
    Something something;

}

@Data
@Builder
@Jacksonized
public class Reservation {
    @NotNull
    Integer reservationLine;
    String reservationDescription;
}

@Data
@Jacksonized
@Builder
public class Something{
    @NotNull
    Integer reservationLineNo;
    @NotNull
    String reservationType;
    String serialNumber;

    public static final List<Something> stuff = new ArrayList<>();

    public Something(@NotNull Integer reservationLineNo, @NotNull String reservationType) {
        this.reservationLineNo = reservationLineNo;
        this.reservationType = reservationType;
        something.add(this);
    }

    public Something(@NotNull Integer reservationLineNo, @NotNull String reservationType, String serialNumber) {
        this.reservationLineNo = reservationLineNo;
        this.reservationType = reservationType;
        this.serialNumber = serialNumber;
        something.add(this);
    }

我创建ItemProduct类的对象如下:

ItemProduct itemProduct = objectMapper.readValue(input_real, ItemProduct.class);

输入:

{
"id": 4011821,
"reservation": {
    "reservationLine": "3",
    "reservationDescription": "xxx"
},
"status": "PROCESSING",
"productType": "TOOL"
}

问题:在构造ItemProduct对象的过程中,我如何构造Something类的对象?使用上面提到的代码,我没有创建Something类的对象。我想调用:ItemProduct类构造函数中的某些内容(this.reservation.reservationLine,this.productType)。
我试着修改为类ItemProduct编写自己的Contractor,但只部分奏效-在反序列化期间使用Builder注解得到了NPE。此外,它生成了许多附加的样板代码(在ItemProduct中将有更多可选的类属性)。
编辑:
肮脏的“解决方案”正在向ItemProduct添加构造函数:

ItemProduct(@NotNull Integer id, @NotNull String status, @NotNull String productType, String productNo, @NotNull Reservation reservation, Something something){
    this.id = id;
    this.status = status;
    this.productType = productType;
    this.reservation = reservation;
    this.productNo = productNo;
    this.something = new Something(reservation.reservationLine, productType);
}

所以,请纠正我,我需要构造函数使用所有可能的属性吗?我需要构造其他的构造函数变量包括未使用的“Something something”参数吗?

cngwdvgl

cngwdvgl1#

在向您指出技术解决方案之前,让我首先解释一下为什么我认为您的设计有缺陷。
一般来说,你应该在设计类时考虑到“关注点分离”原则。ItemProductReservation类的主要关注点是反序列化。然而,Something的关注点似乎是完全不同的东西,尽管还不清楚是什么(存储保留的一些状态?保存内部数据?)。
我的建议是在你的代码中也要分离这些关注点,你可以通过几种方法来实现这一点,一种方法是将输入类Map到一组不同的类;你可以手动或者使用像MapStruct这样的辅助工具。
如果你仍然想要一个技术解决方案,你可以手动为ItemProduct实现一个all-args构造函数。Jackson将使用ItemProductBuilder.build()构造示例,并调用这个构造函数。所以如果你想填充something,这是一种方法。
另一种解决方案是为something创建一个手动getter,并在第一次调用该方法时在其中惰性地创建示例。
PS:你应该瞄准不可变的类。所以如果可能的话,使用@Value而不是@Data。如果你有一个构建器,你也不需要比一个(私有)全参数构造器更多的东西,因为你总是使用构建器来创建示例。

相关问题