2

我有 5 个控制器,我想InitBinder向所有控制器注册一个。

我知道我可以将此代码添加到每个人。

@InitBinder
public void initBinder(WebDataBinder binder)
{
    binder.registerCustomEditor(StringWrapper.class, new StringWrapperEditor());
}

我只想定义一次(甚至创建一个 beanStringWrapperEditor并使用它,而不是每次都创建新的。)

我搜索了 SO 和其他一些地方,但没有找到任何答案。甚至可能吗?

我在 java 1.6 中使用 spring 3.1.1。

4

2 回答 2

2

实现一个PropertyEditorRegistrar注册所有自定义的PropertyEditors. 然后在您的配置中添加一个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。您可以使用 aBeanPostProcessor来处理和配置 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.

如果您没有标签,您可以简单地手动配置 aRequestMappingHandlerAdapter并将所有内容连接在一起。

链接

  1. PropertyEditorRegistrar javadoc
  2. ConfigurableWebBindingInitializer javadoc
  3. 参考指南链接
于 2014-01-16T15:18:02.133 回答
1

尽管最初的问题是关于 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
    ...
于 2019-07-12T10:08:14.437 回答