如何将自定义版本的WebDataBinder注入Spring 3 MVC?
我写了一个WebDataBinder的自定义实现。 在将来,我想对它进行增强,以便它在类本身上寻找注释,并确定它是否应该绑定数据。
如何将此类注入到Spring上下文中以代替WebDataBinder?
我想要的是,如果我运行此代码,我的WebDataBinder版本将被注入,而不是默认的Spring。
@Controller public class MyFormController { @InitBinder public void initBinder(WebDataBinder binder) { // ... } // ... }
我自定义的WebDataBinder实现。 它允许我按类而不是方法名称排除数据绑定。
package com.companyname.spring; import org.springframework.beans.MutablePropertyValues; import org.springframework.util.StringUtils; import org.springframework.web.bind.WebDataBinder; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class CustomDataBinder extends WebDataBinder { List disallowedClasses = new ArrayList(); public CustomDataBinder(Object target) { super(target); } public CustomDataBinder(Object target, String objectName) { super(target, objectName); } public CustomDataBinder disallowClass(Class... classes) { Collections.addAll(disallowedClasses, classes); return this; } @Override protected void doBind(MutablePropertyValues mpvs) { if(disallowedClasses.contains(getTarget().getClass())) { if (logger.isDebugEnabled()) { logger.debug("DataBinder will not bind class [" + getTarget().getClass().getSimpleName() + "] because it appears in the list of disallowed classes [" + StringUtils.collectionToCommaDelimitedString(disallowedClasses) + "]"); } } else { super.doBind(mpvs); } } }
EDIT1
第一次通过,遇到AsyncSupportConfigurer问题
@Configuration @ComponentScan(basePackageClasses = RootContextConfig.class) @EnableTransactionManagement @EnableWebSecurity @EnableAsync @EnableSpringConfigured @EnableLoadTimeWeaving public class RootContextConfig extends WebMvcConfigurationSupport { @Bean public RequestMappingHandlerAdapter requestMappingHandlerAdapter() { List argumentResolvers = new ArrayList(); addArgumentResolvers(argumentResolvers); List returnValueHandlers = new ArrayList(); addReturnValueHandlers(returnValueHandlers); RequestMappingHandlerAdapter adapter = new CustomRequestMappingHandlerAdapter(); adapter.setContentNegotiationManager(mvcContentNegotiationManager()); adapter.setMessageConverters(getMessageConverters()); adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer()); adapter.setCustomArgumentResolvers(argumentResolvers); adapter.setCustomReturnValueHandlers(returnValueHandlers); AsyncSupportConfigurer configurer = new AsyncSupportConfigurer(); configureAsyncSupport(configurer); //All the methods called off of configurer are giving me errors because they have protected level access. I'm not really sure how they're being called in the code I copied this from. if (configurer.getTaskExecutor() != null) { adapter.setTaskExecutor(configurer.getTaskExecutor()); } if (configurer.getTimeout() != null) { adapter.setAsyncRequestTimeout(configurer.getTimeout()); } adapter.setCallableInterceptors(configurer.getCallableInterceptors()); adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors()); return adapter; }
自定义RequestMappingHandlerAdapter
package com.companyname.dirtylibs.spring; import org.springframework.web.method.annotation.InitBinderDataBinderFactory; import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory; import java.util.List; public class CustomRequestMappingHandlerAdapter extends RequestMappingHandlerAdapter { @Override protected InitBinderDataBinderFactory createDataBinderFactory(List binderMethods) throws Exception { return new CustomInitBinderDataBinderFactory(binderMethods, getWebBindingInitializer()); } }
自定义InitBinderDataBinderFactory
package com.companyname.dirtylibs.spring; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebBindingInitializer; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.bind.support.WebRequestDataBinder; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.annotation.InitBinderDataBinderFactory; import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.servlet.mvc.method.annotation.ServletRequestDataBinderFactory; import java.util.List; public class CustomInitBinderDataBinderFactory extends InitBinderDataBinderFactory { /** * Create a new instance. * * @param binderMethods {@code @InitBinder} methods, or {@code null} * @param initializer for global data binder intialization */ public CustomInitBinderDataBinderFactory(List binderMethods, WebBindingInitializer initializer) { super(binderMethods, initializer); } @Override protected CustomDataBinder createBinderInstance(Object target, String objectName, NativeWebRequest webRequest) throws Exception { return new CustomDataBinder(target, objectName); } }
这不是一项简单的任务。 Spring允许进行大量的自定义,但是,该死的,这种变化并不好玩。
您需要扩展RequestMappingHandlerAdapter
类并重写以下方法
/** * Template method to create a new InitBinderDataBinderFactory instance. * The default implementation creates a ServletRequestDataBinderFactory. * This can be overridden for custom ServletRequestDataBinder subclasses. * @param binderMethods {@code @InitBinder} methods * @return the InitBinderDataBinderFactory instance to use * @throws Exception in case of invalid state or arguments */ protected InitBinderDataBinderFactory createDataBinderFactory(List binderMethods) throws Exception { return new ServletRequestDataBinderFactory(binderMethods, getWebBindingInitializer()); }
您需要返回返回自定义WebDataBinder
实例的自定义InitBinderDataBinderFactory
,而不是返回ServletRequestDataBinderFactory
。
此更改意味着您无法使用默认的@EnableWebMvc
或
配置。 这是因为默认情况下它们使用RequestMappingHandlerAdapter
,但您需要注册自己的类。
但是,您可以覆盖@Bean
注释的WebMvcConfigurationSupport#requestMappingHandlerAdapter()
方法,并提供自己的实现来返回自己的类型。 查看该实现对提示的作用。
- Java动态代理 – 如何引用具体类
- 每个循环工作的Java
- java中的静态方法
- AutoCompleteDecorator正在中断ItemListener
- 保存后刷新并获取实体(JPA / Spring Data / Hibernate)
- 在Selenium WebDriver中区分b / w getText()和getAttribute()?
- 更好的理解 – Class.forName(“com.mysql.jdbc.Driver”)。newInstance();
- Spring 4.3.0.RELEASE + Hibernate 5.2.0.Final + JPA Repository
- Java – Char读取文本文件Char的最快方法