我有一个这样的模型:
public class PersonDto {
private CarDto car;
public CarDto getCar() {
return car;
}
public void setCar(CarDto car) {
this.car = car;
}
public static class CarDto {
private String model;
private String color;
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
}
VO是不可改变的:
public class PersonVo {
private final CarDto car;
public PersonVo(CarDto car) {
super();
this.car = car;
}
public CarDto getCar() {
return car;
}
public static class CarDto {
private final String model;
private final String color;
public CarDto(String model, String color) {
super();
this.model = model;
this.color = color;
}
public String getModel() {
return model;
}
public String getColor() {
return color;
}
}
}
使用ModelMapper
提供商是否可以轻松地将此方案从Dto转换为Vo?
我无法使用PersonVo
的一个提供程序弄明白,因为当我创建新对象时,我不知道如何解析CarDto
...
public class PersonVoProvider implements Provider<PersonVo> {
public PersonVo get(org.modelmapper.Provider.ProvisionRequest<PersonVo> request) {
PersonDto source = PersonDto.class.cast(request.getSource());
return new PersonVo(car); ????????????
}
}
答案 0 :(得分:1)
要将一个实例转换为另一个不可更改的实例,请执行以下步骤(总结:1。创建Provider
,2。创建Converter
,3。将两者都添加到ModelMapper configuration
) :
首先使用Provider
类创建一个AbstractProvider
以避免实例化目标错误(Failed to instantiate instance of destination com.example.pregunta.PersonVo. Ensure that com.example.pregunta.PersonVo has a non-private no-argument constructor
)。您的Provider
应该实例化您的不可变类(在您的情况下为PersonVo
),甚至属性都是最终的,具有您想要的值,因为此实例化只是为了避免实例化错误。例如:
Provider<PersonVo> providerVo = new AbstractProvider<PersonVo>() {
@Override
protected PersonVo get() {
PersonVo.CarDto carDto = new PersonVo.CarDto("", "");
PersonVo personVo = new PersonVo(carDto);
return personVo;
}
};
然后,您需要创建一个包含来源Converter
和目标PersonDto
的{{1}}。用手将一个实例转换为另一个实例,如下一个示例所示:
PersonVo
最后,需要将提供程序和转换器添加到Converter<PersonDto, PersonVo> converterDtoToVo = new Converter<PersonDto, PersonVo>() {
@Override
public PersonVo convert(MappingContext<PersonDto, PersonVo> context) {
PersonDto dto = context.getSource();
String color = dto.getCar().getColor();
String model = dto.getCar().getModel();
PersonVo.CarDto carVo = new PersonVo.CarDto(color, model);
PersonVo vo = new PersonVo(carVo);
return vo;
}
};
实例配置中:
ModelMapper
我已经尝试过这个例子而且效果很好:
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setProvider(providerVo);
mapper.addConverter(converterDtoToVo);
输出:
PersonVo [car = CarDto [model = blue,color = Picasso]]
答案 1 :(得分:0)
该示例使用lombok immutable对象解决了该问题,并使用modelMapper
嵌套了immutable唯一的事情是我们必须将accessLevel设置为private并将构造函数声明为private以保持不变性,lombok为我们注释。 请参阅以下示例:
首先定义modelMapper,将accesLevel设置为private
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);
和不可变对象:
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Value
@Builder
public class UserDto {
private final Long id;
private final String uid;
private final String description;
private final boolean enabled;
@Singular
private final Set<GroupUserDto> userGroups;
}
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
public class GroupUserDto {
private Long id;
private String name;
private String description;
private String comments;
private boolean enabled;
}
最后,使用Builder父类调用modelMapper.map可以正常工作。映射的所有字段都包含嵌套的immutable dto
UserDto dto = modelMapper.map(user,UserDto.UserDtoBuilder.class).build();