Spiff
Spiff

Reputation: 2286

Spring MVC - PropertyEditor not called during ModelAttribute type conversion

Using Spring 3.2.3, I'm trying to implement a simple CRUD controller that handles REST-ful URLs. It relies on a PropertyEditor to convert a path variable to a BusinessService entity by loading it from an application service. Code is as follows:

@Controller
public class BusinessServiceController {
    @Autowired
    private BusinessServiceService businessSvcService;

    public BusinessServiceController() {
    }

    @InitBinder
    public void initBinder(final WebDataBinder binder) {
        binder.registerCustomEditor(BusinessService.class, new BusinessServicePropertyEditor(businessSvcService));
    }

    @RequestMapping(value = "/ui/account/business-services/{businessSvc}", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public ModelAndView update(@ModelAttribute("businessSvc") @Valid final BusinessService businessSvc, final BindingResult result,
            final RedirectAttributes redirectAttribs) throws UnknownBusinessServiceException {
        ModelAndView mav;

        if (result.hasErrors()) {
            mav = new ModelAndView("/business-service/edit");
        }
        else {
            businessSvcService.updateBusinessService(XSecurity.principal().getId(), businessSvc);

            mav = new ModelAndView("redirect:/ui/account/business-services");
            redirectAttribs.addFlashAttribute("message", Message.info("businessService.updated", businessSvc.getTitle()));
        }

        return mav;
    }
}

public class BusinessServicePropertyEditor extends PropertyEditorSupport {
    private final BusinessServiceService businessSvcService;

    public BusinessServicePropertyEditor(final BusinessServiceService businessSvcService) {
        this.businessSvcService = businessSvcService;
    }

    @Override
    public String getAsText() {
        final BusinessService svc = (BusinessService) getValue();
        return Long.toString(svc.getId());
    }

    @Override
    public void setAsText(final String text) {
        final BusinessService svc = businessSvcService.getBusinessService(Long.parseLong(text));
        setValue(svc);
    }
}

According to SPR-7608, starting from Spring 3.2, @ModelAttribute method argument resolution checks if a path variable by the same name exists (it does here), in which case it tries to convert that path variable's value to the target parameter type through registered Converters and PropertyEditors. This is not what I'm experiencing. When I inspect what ServletModelAttributeMethodProcessor does, it clearly uses the request DataBinder's ConversionService to perform type conversion, which does not consider registered PropertyEditors, and hence BusinessServicePropertyEditor#setAsText is never called.

Is this a configuration problem or an actual bug?

Thanks for your help!

Upvotes: 1

Views: 1292

Answers (1)

Pavel Horal
Pavel Horal

Reputation: 18214

Spring's ConversionService and Converters are replacement for standard Java Beans PropertyEditors.

You need to implement Converter instead of PropertyEditor if this feature is based purely on conversion service.


To register your custom converters in WebDataBinder you might use ConfigurableWebBindingInitializer or @InitBinder method.

Upvotes: 1

Related Questions