Spring中的PropertyEditor、Formatter和Converter有什么区别?

What is the difference between PropertyEditor, Formatter and Converter in Spring?

使用 Spring MVC 结果证明我可以用许多不同的方式绑定我的表单,我真的觉得自己迷路了。 Formatterparseprint 方法等同于具有不同名称(getAsTextsetAsText)的 PropertyEditorSupport 的方法。同样,我可以实现一个 GenericConverter 或两个 Converter<S,T> 来做完全相同的事情。

我在评论中读到 here FormattersPropertyEditor 的替代品,但我还没有找到任何支持它的文档,它甚至还没有被弃用都没有。

我的问题是,在将数据从表单绑定到对象时,在 spring-mvc 中正确的做法是什么? Spring中的PropertyEditorFormatterConverter之间的主要区别是什么?每个的用例是什么?对我来说,他们似乎有同样的责任。

为了帮助理解这些概念,我首先将 Spring 特定功能与 Java.

公开的功能区分开来

PropertyEditors 和 the related stuff are defined by the JavaBeans Specification.

该规范定义了 API 机制和约定,用于处理对象、对象属性以及与其更改相关的所有内容,如事件。

PropertyEditors 通常用于 GUIs 来处理 UI 和底层对象模型之间的交互,通常处理属性值之间的转换 from/to 它的 String 代表。

Spring 本身实际上在许多不同的情况下使用不同的 PropertyEditor 实现和 Java Beans 约定。例如,来自 docs:

A couple of examples where property editing is used in Spring:

  • Setting properties on beans is done by using PropertyEditor implementations. When you use String as the value of a property of some bean that you declare in an XML file, Spring (if the setter of the corresponding property has a Class parameter) uses ClassEditor to try to resolve the parameter to a Class object.

  • Parsing HTTP request parameters in Spring’s MVC framework is done by using all kinds of PropertyEditor implementations that you can manually bind in all subclasses of the CommandController.

总而言之,PropertyEditors 允许您使用更多的案例。

现在,在 Spring 世界中,您还需要区分 Spring MVC 和 Spring Core。

请注意,Convert and the Formatter 都被定义为核心技术,与任何用例相关,不限于 Web 框架。

Spring 文档在描述 Spring Field Formatting 时,对每个 API/SPI 的用途以及它们与 PropertyEditor 的关系提供了很好的解释:

As discussed in the previous section, core.convert is a general-purpose type conversion system. It provides a unified ConversionService API as well as a strongly typed Converter SPI for implementing conversion logic from one type to another. A Spring container uses this system to bind bean property values. In addition, both the Spring Expression Language (SpEL) and DataBinder use this system to bind field values. For example, when SpEL needs to coerce a Short to a Long to complete an expression.setValue(Object bean, Object value) attempt, the core.convert system performs the coercion.

Now consider the type conversion requirements of a typical client environment, such as a web or desktop application. In such environments, you typically convert from String to support the client postback process, as well as back to String to support the view rendering process. In addition, you often need to localize String values. The more general core.convert Converter SPI does not address such formatting requirements directly. To directly address them, Spring 3 introduced a convenient Formatter SPI that provides a simple and robust alternative to PropertyEditor implementations for client environments.

In general, you can use the Converter SPI when you need to implement general-purpose type conversion logic — for example, for converting between a java.util.Date and a Long. You can use the Formatter SPI when you work in a client environment (such as a web application) and need to parse and print localized field values. The ConversionService provides a unified type conversion API for both SPIs.

在 Spring MVC 的特定用例中,框架本身能够在 handling the HTTP requests 时处理简单类型。

Type conversion is automatically applied based on the configured set of converters, although that behavior can be tweaked using DataBinders and the aforementioned Formatting system. Please, see the relevant docs.

在处理读取和写入 HTTP 请求和响应正文的典型用例中,当使用 @RequestBody, for example, Spring will use a bunch of different pre-configured HttpMessageConverter implementations: the actual ones registered will depend on your configuration and the libraries imported in your project - say Jackson, for example. I was unable to find that point in the documentation but here is the link to the actual source code.

请考虑评论,它可能会有所帮助。