InitBinder 从字面意思可以理解为初始化绑定器的意思。
在Spring Web MVC框架中,@InitBinder注解用于在控制器(Controller)中自定义数据绑定的过程。
当表单数据或请求参数被绑定到JavaBean或命令对象(command object)时,Spring会执行一些默认的转换和验证。
但是,有时候我们可能需要自定义这个绑定过程,例如添加自定义的数据编辑器(DataEditor)、自定义的数据格式化器(Formatter)或者进行一些通用的属性设置。
@InitBinder注解允许我们在控制器中定义一个或多个方法来初始化数据绑定器(DataBinder)。当请求映射到控制器的方法时,这些初始化方法会被调用,从而为数据绑定器提供自定义配置。
一、@InitBinder源码
/*** 自定义初始化数据绑定器 */@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface InitBinder {// 默认情况下,应用于控制器的所有方法,可以使用value进行限制 String[] value() default {};}
@InitBinder 注解只能应用在方法上。
二、最佳实践
1、参数绑定示例
@Controllerpublic class MyController {
@InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(User.class, new UserPropertyEditor());
// 默认情况下同时使用构造函数绑定和属性绑定 // 只使用构造函数绑定时,可以设置setDeclarativeBinding为true // binder.setDeclarativeBinding(true);
// 只绑定某一个属性 binder.setAllowedFields("oldEmailAddress", "newEmailAddress");
// 绑定验证 // binder.addValidators(userValidators); }
@RequestMapping("/saveUser") public String saveUser(@ModelAttribute("user") User user) { // 保存用户逻辑 return "success"; }}
在此示例中,initBinder 方法注册了一个自定义编辑器,用于将请求参数绑定到 User 对象上。
2、类型转换示例
@Controllerpublic class MyController {
@InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(LocalDate.class, new LocalDatePropertyEditor()); }
@RequestMapping("/saveDate") public String saveDate(@RequestParam("date") LocalDate date) { // 处理数据逻辑 return "success"; }}
在这个示例中,initBinder 方法注册了一个自定义编辑器,用于将请求参数转换为 LocalDate 类型。
3、属性格式化示例
@Controllerpublic class MyController {
@InitBinder public void initBinder(WebDataBinder binder) { binder.addCustomFormatter(new DateFormatter("yyyy-MM-dd")); }
@RequestMapping("/saveDate") public String saveDate(@RequestParam("date") @DateTimeFormat(pattern="yyyy-MM-dd") LocalDate date) {// 保存日期逻辑 return "success"; }}
在此示例中,initBinder 方法添加了一个自定义的日期格式化器,用于将请求参数格式化为指定的日期格式。
4、限定使用范围
@Controllerpublic class MyController { // 应用于控制器中的所有方法 @InitBinder public void initBinder(WebDataBinder binder) { System.out.println("不使用value"); System.out.println(binder.getTarget()); }
// 应用于只包含user参数的方法 @InitBinder("user") public void initUserBinder(WebDataBinder binder) { System.out.println("使用value"); System.out.println(binder.getTarget()); }
@RequestMapping("/someEndpoint") public String handleRequest() { // 控制器逻辑 return "viewName"; }
@RequestMapping("/saveUser") public String saveUser(@ModelAttribute("user") User user) { // 保存用户逻辑 return "success"; }}
在这个示例中,第一个 @InitBinder 方法没有指定 value,因此会应用于所有的方法和请求参数。
第二个 @InitBinder 方法指定了 value 为 "user",因此只会应用于包含参数名为 "user" 的方法。这样可以使得不同的初始化逻辑应用于不同方法和参数组。
三、最后总结
在 @Controller 中,@InitBinder 注解的方法适用于控制器内部。而在 @ControllerAdvice 中,@InitBinder 注解的方法可以应用于所有或一部分控制器。
通过@InitBinder注解的方法,我们可以注册自定义的PropertyEditor、Formatter、Converter等,以控制如何将请求参数转换为JavaBean的属性值。
领取专属 10元无门槛券
私享最新 技术干货