一尘不染

Spring MVC类型转换:PropertyEditor还是Converter?

spring

我正在寻找在Spring MVC中绑定和转换数据的最简单方法。如果可能,不进行任何xml配置。

到目前为止,我一直在像这样使用PropertyEditors:

public class CategoryEditor extends PropertyEditorSupport {

    // Converts a String to a Category (when submitting form)
    @Override
    public void setAsText(String text) {
        Category c = new Category(text);
        this.setValue(c);
    }

    // Converts a Category to a String (when displaying form)
    @Override
    public String getAsText() {
        Category c = (Category) this.getValue();
        return c.getName();
    }

}

...
public class MyController {

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

    ...

}

很简单:两个转换都在同一个类中定义,并且绑定很简单。如果我想在所有控制器之间进行常规绑定,则仍可以在xml config中添加3行。

但是Spring 3.x引入了一种使用Converters的新方法:

在Spring容器中,此系统可用作PropertyEditors的替代方案

假设我要使用Converters,因为它是“最新的替代方案”。我将不得不创建两个转换器:

public class StringToCategory implements Converter<String, Category> {

    @Override
    public Category convert(String source) {
        Category c = new Category(source);
        return c;
    }

}

public class CategoryToString implements Converter<Category, String> {

    @Override
    public String convert(Category source) {
        return source.getName();
    }

}

第一个缺点:我必须上两节课。好处:由于通用性而无需强制转换。

然后,如何简单地将数据绑定到转换器?

第二个缺点:我没有找到在控制器中执行此操作的任何简单方法(注释或其他编程工具):像someSpringObject.registerCustomConverter(...);

我发现的唯一方法将是乏味的,不简单的,并且仅关于常规的跨控制器绑定:

XML配置:

<bean id="conversionService"
  class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="somepackage.StringToCategory"/>
            <bean class="somepackage.CategoryToString"/>
        </set>
    </property>
</bean>

Java配置(仅在Spring 3.1+中):

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    protected void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToCategory());
        registry.addConverter(new CategoryToString());
    }

}

有所有这些缺点,为什么要使用Converters?我想念什么吗?还有其他我不知道的技巧吗?

我很想继续使用PropertyEditors …绑定更加容易和快捷。


阅读 876

收藏
2020-04-12

共1个答案

一尘不染

有所有这些缺点,为什么要使用Converters?我想念什么吗?还有其他我不知道的技巧吗?

不,我认为你已经非常全面地描述了PropertyEditor和Converter,以及如何声明和注册它们。

在我看来,PropertyEditor的范围有限-它们有助于将String转换为类型,并且该字符串通常来自UI,因此使用@InitBinder和WebDataBinder注册PropertyEditor才有意义。

另一方面,Converter更通用,它旨在用于系统中的任何转换-不仅用于与UI相关的转换(从字符串到目标类型)。例如,Spring Integration广泛使用转换器将消息有效负载转换为所需类型。

我认为对于UI相关的流,PropertyEditor仍然是合适的,特别是对于需要为特定命令属性进行自定义的情况。对于其他情况,我将从Spring参考中获得建议,并编写一个转换器(例如,将Long ID转换为实体,例如作为示例)。

2020-04-12