Как динамически отобразить список дочерних объектов того же родительского класса в Java - PullRequest
0 голосов
/ 11 ноября 2019

Используя SpringBoot, в качестве ответа REST мой контроллер должен вернуть список MenuDTO, который является родительским классом SimpleMenuDTO и TastingMenuDTO.

Я использую 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.

ОБНОВЛЕНИЕ Основная проблема здесь заключается в том, как динамически отобразить список SimpleMenuEntity и TastingMenuEntity во время выполнения.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2019

Я понял. Я должен настроить маппер так:

        mapper.createTypeMap(TastingMenuEntity.class, MenuDTO.class)
        .setConverter(mappingContext -> mapper.map(mappingContext.getSource(), TastingMenuDTO.class));
        mapper.createTypeMap(SimpleMenuEntity.class, MenuDTO.class)
        .setConverter(mappingContext -> mapper.map(mappingContext.getSource(), SimpleMenuDTO.class));

Итак, окончательный метод картирования будет следующим:

    public MenuDTO map(MenuEntity entity) {
        ModelMapper mapper = new ModelMapper();
        mapper.createTypeMap(TastingMenuEntity.class, MenuDTO.class)
        .setConverter(mappingContext -> mapper.map(mappingContext.getSource(), TastingMenuDTO.class));

        mapper.createTypeMap(SimpleMenuEntity.class, MenuDTO.class)
        .setConverter(mappingContext -> mapper.map(mappingContext.getSource(), SimpleMenuDTO.class));

        return mapper.map(entity, MenuDTO.class);
    }
0 голосов
/ 11 ноября 2019

Добавьте Джексона в качестве зависимости проекта:

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

, затем используйте @JsonTypeInfo для вывода поля @type , которое может использоваться получателями для различения различных меню.

@JsonTypeInfo(use=Id.NAME)
@JsonSubTypes({
  @JsonSubTypes.Type(value=SimpleMenuDTO.class, name="Simple"),
  @JsonSubTypes.Type(value=TastingMenuDTO.class, name="Tasting")
})
public class MenuDTO {
}

, что может дать JSON вроде:

{
  // Type-specific elements
  "@type" : "Tasting",
  "price" : "10.0",

  // Common elements
  "description" : "",
  "restaurantId" : 1,
  "name" : ""
}

Если вам не нравится @type, выберите свое имя с помощью @JsonTypeInfo(use=Id.NAME, property="menuType")

...