Using SpringBoot, as REST response, my controller has to return a list of MenuDTO
which is a parent class of SimpleMenuDTO
and TastingMenuDTO
.
I am using ModelMapper to map entity to 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;
}
How can I handle this situation?
I am able to change the entities and DTOs.
UPDATE The main problem here is how to dynamically map a list of SimpleMenuEntity
and TastingMenuEntity
in runtime.
I got it. I have to configure the mapper like this:
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));
So, the final mapping method would be as follows:
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);
}
Add Jackson as a project dependency:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
then use @JsonTypeInfo
to output a @type
field that can be used by recipients to distinguish different menus.
@JsonTypeInfo(use=Id.NAME)
@JsonSubTypes({
@JsonSubTypes.Type(value=SimpleMenuDTO.class, name="Simple"),
@JsonSubTypes.Type(value=TastingMenuDTO.class, name="Tasting")
})
public class MenuDTO {
}
which might give JSON like:
{
// Type-specific elements
"@type" : "Tasting",
"price" : "10.0",
// Common elements
"description" : "",
"restaurantId" : 1,
"name" : ""
}
If you don't like @type
then choose your own name with @JsonTypeInfo(use=Id.NAME, property="menuType")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.