Spring MVC - 在ModelAttribute类型转换期间未调用PropertyEditor

时间:2013-06-15 22:51:03

标签: spring-mvc type-conversion

使用Spring 3.2.3,我正在尝试实现一个处理REST-ful URL的简单CRUD控制器。它依赖于PropertyEditor,通过从应用程序服务加载它来将路径变量转换为BusinessService实体。代码如下:

@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);
    }
}

根据SPR-7608,从Spring 3.2开始,@ ModelAttribute方法参数解析检查是否存在同名的路径变量(它在这里),在这种情况下,它尝试将该路径变量的值转换为目标参数类型通过注册的转换器和PropertyEditors。这不是我所经历的。当我检查ServletModelAttributeMethodProcessor的作用时,它明确地使用请求DataBinder的ConversionService来执行类型转换,它不考虑注册的PropertyEditors,因此永远不会调用BusinessServicePropertyEditor #setAsText。

这是配置问题还是实际错误?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

Spring的ConversionServiceConverter是标准Java Bean PropertyEditor的替代品。

如果此功能完全基于转化服务,则需要实施Converter而不是PropertyEditor


要在WebDataBinder中注册自定义转换器,您可以使用ConfigurableWebBindingInitializer@InitBinder方法。