现在的位置: 首页 > 综合 > 正文

Spring表单的initBinder:绑定表单复杂属性

2012年11月29日 ⁄ 综合 ⁄ 共 2744字 ⁄ 字号 评论关闭
文章目录
今天碰到一个问题,页面表单上是一个id,但在表单控制器的command里是一个javabean,如果将一个String转换成javabean呢?因为已经有了一个服务于hibernate的javabean,我可不想再写一个javabean,然后再笨笨的转换。

在查看SimpleFormController的API的时候,发现它有一个来自父类BaseCommandController的方法——initBinder:
BaseCommandController (Spring Framework)

initBinder

protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception
Initialize the given binder instance, for example with custom editors. Called by de<createBinderde<.

This method allows you to register custom editors for certain fields of your command class. For instance, you will be able to transform Date objects into a String pattern and back, in order to allow your JavaBeans to have Date properties and still be able to set and display them in an HTML interface.

Default implementation is empty.

Parameters:
de<requestde< - current HTTP request
de<binderde< - new binder instance

----------------------------------------------笨拙的分割线----------------------------------------
回想以前学习IoC容器的时候,有提到“属性编辑器”,只要在IoC配置文件里注册特定“编辑器”,就可以将String转换成javabean。
翻了翻书,想要自定义属性编辑器,只要继承PropertyEditorSupport,并重写里面的setAsText方法,再进行注册就行了。只不过书上是在IoC容器的配置文件注册,而这里恐怕是通过重写initBinder方法注册。
initBinder有一个入参binder就是用来注册属性编辑器的,它是ServletRequestDataBinder类型,查看API,有一个来自父类DataBinder的方法——registerCustomEditor:
DataBinder (Spring Framework)

public void registerCustomEditor(Class requiredType, String field, PropertyEditor propertyEditor)
Description copied from interface: de<PropertyEditorRegistryde<

Register the given custom property editor for the given type and property, or for all properties of the given type.

If the property path denotes an array or Collection property, the editor will get applied either to the array/Collection itself (the PropertyEditor has to create an array or Collection value) or to each element (the PropertyEditor has to create the element type), depending on the specified required type.

Note: Only one single registered custom editor per property path is supported. In case of a Collection/array, do not register an editor for both the Collection/array and each element on the same property.

------------------------------------------愚蠢的分割线--------------------------------

方法的入参名已经很明显地暴露了意图。requiredType显然是指command里的javabean,field显然是指在command里对应的字段名,同时也是表单里对应的name,而propertyEditor就是自定义的属性编辑器。

例子:
//自定义属性编辑器
public class CollegeEditor extends PropertyEditorSupport{
    private CollegeService collegeService;

    public CollegeService getCollegeService() {
        return collegeService;
    }

    public void setCollegeService(CollegeService collegeService) {
        this.collegeService = collegeService;
    }
    
    public void setAsText(String collegeId){
        int id = Integer.valueOf(collegeId);
        College college = collegeService.findCollegeById(id);
        setValue(college);
    }
}
//重写SimpleFormController的initBinder方法
public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder){
        binder.registerCustomEditor(College.class, "college", collegeEditor);
    }

当然不要忘记IoC容器里该注入的要注入。

抱歉!评论已关闭.