我想使用自定义WebArgumentResolver作为id - >实体。如果我使用请求参数,则足够简单:使用参数键确定实体类型并相应地查找。
但我希望它像@PathVariable注释一样。
例如
http://mysite.xzy/something/enquiryId/itemId会触发此方法
@RequestMapping(value = "/something/{enquiry}/{item}")
public String method(@Coerce Enquiry enquiry, @Coerce Item item)
@ Coerce注释会告诉WebArgumentResolver根据它的类型使用特定服务。
问题在于哪个uri部分属于实体。
有人可以解释PathVariable注释是如何做到的。是否可以使用我的自定义注释来模拟它。
感谢。
答案 0 :(得分:10)
您可以使用@InitBinder 让spring知道如何将给定的字符串强制转换为自定义类型。
你想要的东西是:
@RequestMapping(value = "/something/{enquiry}")
public String method(@PathVariable Enquiry enquiry) {...}
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Enquiry.class, new PropertyEditorSupport() {
@Override
public String getAsText() {
return ((Enquiry) this.getValue()).toString();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
setValue(new Enquiry(text));
}
});
}
答案 1 :(得分:2)
对于通用方法,您不需要为每个实体指定一个PropertyEditor,您可以使用ConditionalGenericConverter:
public final class GenericIdToEntityConverter implements ConditionalGenericConverter {
private static final Logger log = LoggerFactory.getLogger(GenericIdToEntityConverter.class);
private final ConversionService conversionService;
@PersistenceContext
private EntityManager entityManager;
@Autowired
public GenericIdToEntityConverter(ConversionService conversionService) {
this.conversionService = conversionService;
}
public Set<ConvertiblePair> getConvertibleTypes() {
return ImmutableSet.of(new ConvertiblePair(Number.class, AbstractEntity.class),
new ConvertiblePair(CharSequence.class, AbstractEntity.class));
}
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return AbstractEntity.class.isAssignableFrom(targetType.getType())
&& this.conversionService.canConvert(sourceType, TypeDescriptor.valueOf(Long.class));
}
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (source == null) {
return null;
}
Long id = (Long) this.conversionService.convert(source, sourceType, TypeDescriptor.valueOf(Long.class));
Object entity = entityManager.find(targetType.getType(), id);
if (entity == null) {
log.info("Did not find an entity with id {} of type {}", id, targetType.getType());
return null;
}
return entity;
}
}