Custom WebArgumentResolver as @PathVariable

I would like to use a custom WebArgumentResolver object for an id β†’ object. Easy enough if I use query parameters: use the parameter key to determine the type of entity and search accordingly.

But I would like it to be like @PathVariable annotation.

eg.

http: //mysite.xzy/something/enquiryId/itemId can call this method

@RequestMapping(value = "/something/{enquiry}/{item}") public String method(@Coerce Enquiry enquiry, @Coerce Item item) 

@ Annotations for commerce will inform WebArgumentResolver about the use of a particular service based on its type.

The problem is which part of the uri belongs to the entity.

Can someone explain how the PathVariable annotation does this. And is it possible to emulate it using my annotation.

Thanks.

+6
java spring spring-annotations spring-mvc
source share
2 answers

You can use @InitBinder so spring knows how to force a given String to your custom type.

You need something like:

 @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)); } }); } 
+9
source share

For a general approach, when you do not need to specify one PropertyEditor for each object, you can use 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; } } 
+1
source share

All Articles