与webDataBinder一起使用,
需要先注册进去,通过
registerCustomEditor(Date, newCustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true))
然后前端可以传入2020-01-02,只在当前controller生效
defaultEditors 是这个类创建的时候,springmvc自动创建的; customEditors 需要我们人工的注册 ,所谓注册就是把private Map<Class<?>, PropertyEditor> customEditors; 这个map进行一个put的操作
PropertyEditor的应用
案例:Controller中有个方法,并且该方法的参数为Date类型。如下图,此时如果直接通过url传入日期数据,会报400错误,说明参数是有问题的。
CustomDateEditor类:MVC编码中,该Editor经常被注册,通过使用binder.registerCustomEditor(这个binder就是之前admin和user
拥有同样的name和age,方法里有个WebDataBinder类型的binder)
registerCustomEditor():它是WebDataBinder对象的方法,该方法在它的父类DataBinder中继承来的,该方法中通过getPropertyEditorRegistry()获得PropertyEditorRegistry对象,它就代表一个注册,PropertyEditorRegistry是一个接口,该接口有很多实现类,其中一个PropertyEditorRegistrySupport实现类,该类有一个Map类型的defaultEditors和customEditors,defaultEditors是这个类创建的时候,SpringMVC自动生成defaultEditors。customEditors需要人工手动进行注册,所谓注册过程就是把Map进行一个put的操作,这里可以通过createDefaultEditors()了解它defaultEditors是如何搜索的,首先对defaultEditors成员变量进行声明,声明成一个HashMap长度为64,然后会放入很多defaultEditors
对于customEditors:下面图片中的上面的registerCustomEditor方法是下面registerCustomEditor方法的重载,中间差了一个参数,该参数就是String propertyPath参数,如果上面的方法传入了一个null,就会调用下面的方法。
对于Date数据类型绑定:
通过@InitBinder("date1")注解,并且在initDate1方法中WebDataBinder对象调用registerCustomEditor(),把这个东西进行注册,因为默认注册是没有Date类型的,但是PropertyEditorSupport进行了扩展,支持很多子类,并把Date类型,转换成CustomDateEditor类型,通过CustomDateEditor的构造器了解,一个参数是DateFormat一个参数是allowEmpty类型,这里new一个SimpleDateFormat
/** *date:2018-05-24 * @param date */ @PostMapping("date") public void dateType(Date date){ System.out.println(date); } /** *date:2018-05-24 * @param date2 */ @PostMapping("date2") public void dateType2(@RequestParam("date") Date date2){ System.out.println(date2); } /** * InitBinder注解的value为指定requestParam的name * 此注解的作用范围在自身所在controller内 * @param binder */ @InitBinder({"date"}) public void initDate(WebDataBinder binder){ //指定处理类型,自定义日期数据处理器,处理器允许requestParam值为空 binder.registerCustomEditor(Date.class,new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"),true)); }
在请求的Url中设置日期类型的字符串传递的时候,报400错,说明日期绑定失败,如何使得Url中的日期与controller方法中入参类型为Date的对象绑定呢?这时,我们就需要注册自定义属性编辑器。如图,@InitBinder("date1")限定参数为date1,通过Url请求时,先执行有此注解的方法,该方法,向数据绑定器注册了新的自定义的属性编辑器,将Date类型的value设置为SimpleDateFormat("yyyy-MM-DD"),假如Url传递的参数为date1=2020-02-20,那么就会将Date参数直接格式化为yyyy-MM-DD格式,并作为controller方法的参数。完成绑定,可见,通过注解实现自定义参数绑定只需要注意两点:①使用注解,绑定传递的参数,形如@InitBinder("date1"),绑定的参数为date1,②基于此注解的方法,必须有一个参数,且参数类型为WebDataBinder,通过调用该对象的registerCustomEdior(_,_)实现自定义属性转换的注册。
之前几个章节我们提到了在处理同级对象的同名属性时,使用注解 @InitBinder 来设置不同的前缀以作区别,这里我们同样用到了这个注解,这次来大概梳理一下。
先看下 @InitBinder 注解的大概说明:用来标记某些方法,初始化WebDataBinder来处理参数。那么我们可以继续看下 WebDataBinder,说明是“为了处理数据绑定,用来将请求中的参数转化为JavaBean对象”,所以我们也就用到了该对象的一个方法registerCustomEditor,而该方法的一个重要的参数类型就是 PropertyEditor,这个接口说明的作用是“提供各种方式展示属性值”
这里涉及到的两个接口 PropertyEditor 和 PropertyEditorRegistry,显然后者是前者的注册器。在注册器的实现类 PropertyEditorRegistrySupport 中我们可以看到其属性就有 defaultEditors 和 customEditors,从命名就可以看出,如果我们使用自定义规则,就需要将自定义的PropertyEditor,通过 registerCustomEditor() 将其注册到 customEditors 中才能使用。那么有两种方式,第一种是我们自定义类继承PropertyEditorSupport间接实现PropertyEditor接口,这在上个章节视频《7-1 介绍》的1:17前后进行了说明;第二种方式就是实际上spring提供了一些简单的实现类,比如日期的编辑器类CustomDateEditor,也就是我们如截图所示意用到的。