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