Spring MVC provides so many cool features to make the controller code as minimal as possible. Converter & the ConversionService is one such feature that will be invoked by the framework to carry out type conversions. I have been looking for a decent example & stackoverflow came to the rescue.
I want to add some more information to the solution. As per the Spring documentation here a URI template variable gets translated to the target object using the Converter/ConversionService. I tried to use a `@RequestParam("id") @ModelAttribute("contact") Contact contact`, but I was getting an `IllegalStateException: Neither BindingResult nor plain target object for bean name 'contact' available as request attribute` for not having the model object `contact` in my view edit.jsp. This can be easily resolved by declaring a `Model model` and `model.addAttribute(contact);`. However, there is an even better way; using the URI template variable. It's strange why `@RequestParam` did not work.
DID NOT WORK
So what does this thing do
.. a link like `...edit/1` implicitly invokes the converter for String '1' to Contact of id '1' conversion, and brings this contact object to the view. No need for `@InitBinder` and since its a `Converter` registered with the `ConversionService` I can use this **anywhere I want - implicitly or explicitly**.
Converter:
@RequestMapping("edit") //Passing id as .. edit?id=1 public String editWithConverter(@RequestParam("id") @ModelAttribute("contact") Contact contact){ logger.info("edit with converter"); return "contact/edit"; }WHAT WORKED
@RequestMapping("edit/{contact}") //Passing id as .. edit/1 public String editWithConverter(@PathVariable("contact") @ModelAttribute("contact") Contact contact){ // STS gave a warning for using {contact} without @PathVariable logger.info("edit with converter"); return "contact/edit"; }
So what does this thing do
.. a link like `...edit/1` implicitly invokes the converter for String '1' to Contact of id '1' conversion, and brings this contact object to the view. No need for `@InitBinder` and since its a `Converter` registered with the `ConversionService` I can use this **anywhere I want - implicitly or explicitly**.
Converter:
public class StringToContactConverter implements Converter <String, Contact > { private static final Logger logger = LoggerFactory .getLogger(StringToContactConverter.class); @Autowired private ContactService contactService; public void setContactService(ContactService contactService) { this.contactService = contactService; } @Override public Contact convert(String id) { logger.info("Converting String to Contact"); Contact contact = contactService.getContact(Long.parseLong(id)); return contact; } }Configuration: servlet-context.xml
<annotation-driven conversion-service="conversionService"/> <beans:bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean" > <beans:property name="converters"> <beans:list> <beans:bean class="com.aj.recipes.web.convert.StringToContactConverter"> </beans:bean></beans:list> </beans:property> </beans:bean>
No comments:
Post a Comment