第1部分
我正在使用JavaModelMapper库(http://modelmapper.org/)管理实体和DTO之间的Map。我有一个联系人(实体)和一个联系人视图(dto)。我在contactview中有一个名为“type”的字符串字段,它在contact中不存在。它的值应该只是实体子类的名称。我试着这样做定制Map:
modelMapper.typeMap(Contact.class, ContactView.class).addMappings(mapper -> {
mapper.map(src -> src.getClass().getSimpleName(), ContactView::setType);
});
我在mapper.map(src->src.getclass().getsimplename(),contactview::settype)处得到一个编译错误;
定义了非法的sourcegetter
org.springframework.beans.factory.support.simpleinstationstrategy.instantiate(simpleinstationstrategy)出现1个错误。java:185)~[ Spring Bean -5.3.2。jar:5.3.2]在org.springframework.beans.factory.support.constructorresolver.instantiate(constructorresolver。java:653)~[ Spring Bean -5.3.2。jar:5.3.2] ... 省略33个公共框架
我甚至试过使用转换器,同样的结果:
modelMapper.typeMap(Contact.class, ContactView.class).addMappings(mapper -> {
Converter<Class, String> toName = ctx -> ctx.getSource() == null ? null : ctx.getSource().getSimpleName();
mapper.using(toName).map(Contact::getClass, ContactView::setType);
});
你知道怎么解决这个问题吗?
第2部分
根据建议的答案,我尝试向modelmapper添加一个转换器类。这是我配置modelmapper bean的地方:
@Configuration
public class Mapper {
@Autowired
private ContactTypeRepository contactTypeRepository;
@Bean
public ModelMapper getMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT);
modelMapper.typeMap(ContactTag.class, ReferenceEntityView.class).addMappings(mapper -> {
mapper.map(src -> src.getTag().getCode(), ReferenceEntityView::setCode);
mapper.map(src -> src.getTag().getValue(), ReferenceEntityView::setValue);
});
modelMapper.typeMap(Person.class, PersonView.class).addMappings(mapper -> {
mapper.skip(PersonView::setName);
mapper.map(Person::getName, PersonView::setLastName);
});
modelMapper.addConverter(new ContactConverter());
return modelMapper;
}
class ContactConverter implements Converter<Contact, ContactView> {
private ModelMapper localMapper = new ModelMapper();
@Override
public ContactView convert(MappingContext<Contact, ContactView> context) {
Contact contact = context.getSource();
ContactView contactView = localMapper.map(contact, ContactView.class);
ContactType contactType = contactTypeRepository.getByCode(context.getSource().getClass().getSimpleName().toLowerCase());
contactView.setType(localMapper.map(contactType, ReferenceEntityView.class));
return contactView;
}
}
}
这就是我使用modelmapper bean生成dto的地方:
@RestController
@RequestMapping(value = "/contacts")
public class ContactController {
@Autowired
private ContactRepository contactRepository;
@Autowired
private ModelMapper modelMapper;
@GetMapping(value = "/{id}")
@ResponseStatus(HttpStatus.OK)
public ContactView findById(@PathVariable("id") Long id){
Contact c = contactRepository.getOne(id);
ContactView cv = modelMapper.map(c, ContactView.class);
return cv;
}
}
由于某些原因,转换器的convert方法未被调用,contactview对象的“type”字段为空。modelmapperbean上的其他Map工作正常。
2条答案
按热度按时间l7wslrjt1#
试试我的图书馆便条。它是一个注解处理器。这意味着jdk将在编译项目之前为您生成类。所以它在编译时完成工作。您可以像自己编写的任何其他类一样使用生成的类。您可以看到生成的类的源代码,因此不再具有魔力。这个库能够为您生成dto类。你不需要改变原来的班级。除了在原始类上配置注解外,还可以选择创建新的配置类,并在其上配置注解。该库支持复制和继承原始类的所有属性,并在此基础上删除、修改或添加属性。对于您的问题:
在某些情况下,beanknife比modelmapper强大得多。例如,如果发生了错误,可以检查生成类的源代码(通常位于/target/generated source/annotations中,在ide上可能不同),并查看原因。如果它真的是一个bug,你可以把这个问题提交给github,我会尽快处理的。
这里有更多的例子。
nhjlsmyf2#
这是因为modelmapper的实现
issynthetic方法的文档中说
如果此成员是由编译器引入的,则返回true;否则返回false。当且仅当编译器引入此成员时返回:true。
我想这就是为什么它不能例外。
对于类似的情况,我们引入了一个特定的Map器类,使用modelmapper作为基本Map器,并设置另一个字段:
为了使它与整体Map保持一致,您可以将其定义为一个转换器,并像这样将其注册到Map中