如何在Java中动态映射相同父类的子对象列表

问题描述 投票:0回答:2

使用SpringBoot,作为REST响应,我的控制器必须返回MenuDTO的列表,该列表是SimpleMenuDTOTastingMenuDTO的父类。

我正在使用ModelMapper将实体映射到DTO。

public abstract class MenuEntity {
    private String name;
    private String description;
    private RestaurantEntity restaurant;
}
public class SimpleMenuEntity extends MenuEntity {
    private final Set<MenuSectionEntity> sections = new HashSet<>();
}
public class TastingMenuEntity extends MenuEntity {
    private BigDecimal price;
    private final Set<ProductEntity> products = new HashSet<>();
}
public class MenuDTO {
    private String name;
    private String description;
    private char menuType;
    private Long restaurantId;
}

我该如何处理这种情况?我可以更改实体和DTO。

UPDATE这里的主要问题是如何在运行时动态映射SimpleMenuEntityTastingMenuEntity的列表。

java rest design-patterns domain-driven-design
2个回答
0
投票

将杰克逊添加为项目依赖项:

    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
    </dependency>

然后使用接收者可以用来区分不同菜单的@JsonTypeInfo to output a @type field

@JsonTypeInfo

这可能会给JSON类似:

@type

如果您不喜欢@JsonTypeInfo(use=Id.NAME) @JsonSubTypes({ @JsonSubTypes.Type(value=SimpleMenuDTO.class, name="Simple"), @JsonSubTypes.Type(value=TastingMenuDTO.class, name="Tasting") }) public class MenuDTO { } ,请用{ // Type-specific elements "@type" : "Tasting", "price" : "10.0", // Common elements "description" : "", "restaurantId" : 1, "name" : "" } 选择您自己的名字


0
投票

我明白了。我必须像这样配置映射器:

@type
@JsonTypeInfo(use=Id.NAME, property="menuType")

因此,最终的映射方法如下:

        mapper.createTypeMap(TastingMenuEntity.class, MenuDTO.class)
        .setConverter(mappingContext -> mapper.map(mappingContext.getSource(), TastingMenuDTO.class));
© www.soinside.com 2019 - 2024. All rights reserved.