我有 5 个控制器,我想为所有控制器注册一个InitBinder
。
我知道我可以将此代码添加到他们每个人中。
@InitBinder
public void initBinder(WebDataBinder binder)
{
binder.registerCustomEditor(StringWrapper.class, new StringWrapperEditor());
}
但我只想定义它一次(甚至创建一个 StringWrapperEditor
bean 并使用它而不是每次都创建新的。
我搜索了SO和其他地方,但没有找到任何answear。甚至可能吗?
我使用 spring 3.1.1 和 java 1.6。
虽然最初的问题是关于Spring 3.1的,但以下内容可能对使用较新Spring版本的人有用。
例如,一种可能的选择是将@InitBinder移动到@ControllerAdvice
@ControllerAdvice
class InitBinderControllerAdvice {
@InitBinder
fun initBinder(dataBinder: WebDataBinder) {
dataBinder.registerCustomEditor(
MLQueryOutputFormat::class.java,
StringToMLQueryOutputFormat()
)
dataBinder.registerCustomEditor(
IDatabaseOps.SortDirection::class.java,
StringToSortDirection()
)
}
}
关于 ConfigurableWebBindingInitializer,尽管它是一个非常强大的功能,但它需要在验证等方面进行额外的配置,因此一旦实现它,请注意细节。例如,以下代码按照 InitBinder 完成工作,但缺少设置验证器。结果,使用 @Validated 注释的其余控制器参数的验证不起作用:
@Configuration
class WebMvcConfig {
@Bean
fun configurableWebBindingInitializer(): ConfigurableWebBindingInitializer {
val initializer = ConfigurableWebBindingInitializer()
initializer.propertyEditorRegistrars = arrayOf(
PropertyEditorRegistrar {
it.registerCustomEditor(
MLQueryOutputFormat::class.java,
StringToMLQueryOutputFormat()
)
}, PropertyEditorRegistrar {
it.registerCustomEditor(
IDatabaseOps.SortDirection::class.java,
StringToSortDirection()
)
}
)
return initializer
}
}
要添加验证,可以执行以下操作:
@Bean
fun configurableWebBindingInitializer(
@Qualifier("defaultValidator") validator: Validator
): ConfigurableWebBindingInitializer {
val initializer = ConfigurableWebBindingInitializer()
initializer.validator = validator
...
实现一个注册所有自定义PropertyEditors
的PropertyEditorRegistrar
。然后在您的配置中添加一个ConfigurableWebBindingInitializer
,您将它与创建的PropertyEditorRegistrar
连接起来,并将其挂接到您的HandlerAdapter
。
public class MyPropertyEditorRegistrar implements PropertyEditorRegistrar {
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(StringWrapper.class, new StringWrapperEditor());
}
}
如果您的配置中有 <mvc:annotation-driven />
标记,则问题是使用此标记无法将WebBindingInitializer
添加到适配器旁边,该适配器旁边已经有一个ConfigurableWebBindingInitializer
添加到预配置的 HandlerAdapter。您可以使用BeanPostProcessor
来处理和配置 Bean。
public class MyPostProcessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
if (bean instanceof RequestMappingHandlerAdapter) {
WebBindingInitializer wbi = ((RequestMappingHandlerAdapter) bean).getWebBindingInitializer();
if (wbi == null) {
wbi = new ConfigurableWebBindingInitializer();
((RequestMappingHandlerAdapter) bean).setWebBindingInitializer(wbi);
}
if (wbi instanceof ConfigurableWebBindingInitializer) {
((ConfigurableWebBindingInitializer) wbi).setPropertyEditorRegistrar(new MyPropertyEditorRegistrar());
}
}
}
}
需要一些工作,但这是可行的。您也可以实现自己的WebBindingInitializer
。
如果您没有标签,您可以简单地手动配置RequestMappingHandlerAdapter
并将所有内容连接在一起。
链接
- PropertyEditorRegistrar javadoc
- ConfigurableWebBindingInitializer javadoc
- 参考指南链接