如何在Spring-MVC中注册全局自定义编辑器?

25

根据需要,我在许多Spring-MVC控制器中使用以下自定义编辑器:

一个控制器

binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, NumberFormat.getNumberInstance(new Locale("pt", "BR"), true));

其他控制器

binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, NumberFormat.getNumberInstance(new Locale("pt", "BR"), true));

另一个控制器

binder.registerCustomEditor(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, NumberFormat.getNumberInstance(new Locale("pt", "BR"), true));

请注意相同的自定义编辑器已注册。

问题:我如何设置全局自定义编辑器,以避免设置每个控制器?

问候,

4个回答

32

从Spring 3.2开始,您可以使用@ControllerAdvice替代在每个控制器中使用@ExceptionHandler、@InitBinder和@ModelAttribute。它们将应用于所有@Controller Bean。

import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;

@ControllerAdvice
public class GlobalBindingInitializer {
  @InitBinder
  public void registerCustomEditors(WebDataBinder binder, WebRequest request) {
    binder.registerCustomEditor(BigDecimal.class, new  CustomNumberEditor(BigDecimal.class, NumberFormat.getNumberInstance(new Locale("pt", "BR"), true));
  }
}
如果您是从Spring Roo生成的代码开始,或者通过使用include-filter来限制被component-scan扫描的注解,那么请在webmvc-config.xml中添加所需的过滤器。
<!-- The controllers are autodetected POJOs labeled with the @Controller annotation. -->
<context:component-scan base-package="com.sensei.encore.maininterface" use-default-filters="false">
  <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
  <!-- ADD THE BELOW LINE -->
  <context:include-filter expression="org.springframework.web.bind.annotation.ControllerAdvice" type="annotation"/>
</context:component-scan>

13

你需要在你的应用上下文中声明它:

<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
  <property name="customEditors"><map>
    <entry key="java.math.BigDecimal">
      <bean class="org.springframework.beans.propertyeditors.CustomNumberEditor">
      ... <!-- specify constructor-args here -->
      </bean>
    </entry>
  </map></property>
</bean>

详细信息请看这里


它会覆盖默认的Spring属性编辑器吗? - Arthur Ronald
是的。我上面链接的页面明确说明了(表5.2.内置属性编辑器)。 - ChssPly76
4
根据Javadoc,“customEditors”属性已被弃用,将在Spring 3中移除。您应该改用“PropertyEditorRegistrars”属性。请注意,翻译时不会添加解释或其他内容。 - skaffman
@skaffman - 你说得对,谢谢。实际上它并没有被标记为弃用(只是在注释中这样说),所以我从来没有注意到。propertyEditorRegistrars 是正确的选择。 - ChssPly76
@skaffman,实际上被弃用的是对PropertyEditor的支持,而不是属性/方法本身。3.0+文档表明他们并没有将其删除(但仍然被弃用)。 - kryger

13
如果您使用基于注释的控制器(Spring 2.5+), 您可以使用WebBindingInitializer来注册全局属性编辑器。类似这样的东西:
public class GlobalBindingInitializer implements WebBindingInitializer {

    public void initBinder(WebDataBinder binder, WebRequest request) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));
    }

}

因此,在您的Web应用程序上下文文件中声明

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="GlobalBindingInitializer"/>
    </property>
</bean>

通过这种方式,所有基于注释的控制器都可以使用在GlobalBindingInitializer中声明的任何属性编辑器。


对我来说,类代码是一个很大的帮助,但是通过Web应用程序上下文文件添加它会导致奇怪的问题。相反,我使用ControllerAdvice注释了类,并使用InitBinder注释了方法,这样做效果很好。 - Guerry

0
一个替代方案是,你可以创建一个抽象类,让你的控制器继承它,而不是使用@ControllerAdvice。
public abstract class BaseController {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // Replace empty strings with nulls for submitted form fields.
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接