与Spring MVC
一起工作,事实证明我可以用许多不同的方式绑定我的表单,我真的觉得我迷路了。Formatter
的parse
和print
方法等同于具有不同名称(getAsText
和setAsText
)的PropertyEditorSupport
的方法。同样,我可以实现一个或两个Converter<S,T>
GenericConverter
来做完全相同的事情。
我在评论中读到Formatters
是PropertyEditor
的替代品,但我还没有找到任何文档来支持它,它甚至也没有被弃用。
我的问题是,当涉及到将数据从表单绑定到对象时,spring-mvc
的正确方法是什么?春季PropertyEditor
、Formatter
和Converter
的主要区别是什么?每个用例是什么?对我来说,看起来他们有同样的责任。
为了帮助理解这些概念,我首先将Spring特定的功能与Java公开的功能区分开来。
PropertyEditor
和相关的东西是由 JavaBeans 规范定义的。
该规范将 API、机制和约定定义为事件,用于处理对象、对象属性以及与其更改相关的所有内容。
PropertyEditor
通常在 GUI 中用于处理 UI 和基础对象模型之间的交互,通常处理属性值与其String
表示之间的转换。
Spring 本身实际上在许多不同的情况下使用不同的PropertyEditor
实现和 Java Beans 约定。例如,从文档中:
在 Spring 中使用属性编辑的几个示例:
- 在
设置 Bean 的属性是通过使用
PropertyEditor
完成的 实现。当您使用字符串作为某些属性的值时 您在 XML 文件中声明的 bean,Spring (如果 对应的属性有一个Class
参数)使用ClassEditor
来尝试 将参数解析为Class
对象。Spring 的 MVC 框架中解析 HTTP 请求参数由 使用可以手动使用的各种
PropertyEditor
实现 绑定在CommandController
的所有子类中。
总之,PropertyEditor
允许您使用更广泛的用例。
现在,在Spring世界中,您还需要区分Spring MVC和Spring Core。
请注意,转换和格式化程序都被定义为核心技术,与任何用例相关,而不限于Web框架。
Spring文档在描述 Spring 字段格式化时,很好地解释了每个 API/SPI 的目的以及它们与PropertyEditor
的关系:
如上一节所述,
core.convert
是通用的 类型转换系统。它提供了一个统一的ConversionService
API 作为 以及用于实现转换逻辑的强类型转换器SPI。 从一种类型到另一种类型。弹簧容器使用此系统绑定豆子 属性值。此外,Spring Expression Language (SpEL)DataBinder
使用此系统绑定字段值。例如,当 SpEL 需要将Short
强制到Long
才能完成expression.setValue(Object bean, Object value)
尝试,core.convert
系统执行强制。现在考虑典型客户端的类型转换要求 环境,例如 Web 或桌面应用程序。在这样的环境中, 通常从
String
转换以支持客户端回发过程, 以及返回到String
以支持视图渲染过程。在 此外,您通常需要本地化String
值。更一般 core.convert 转换器 SPI 不能满足此类格式化要求 径直。为了直接解决这些问题,Spring 3 引入了一个方便 格式化程序 SPI,提供简单而强大的替代方案PropertyEditor
客户端环境的实现。通常,当您需要实现时,可以使用转换器 SPI。 通用类型转换逻辑 — 例如,用于在 一个
java.util.Date
和一个Long
.您可以在以下情况下使用格式化程序 SPI: 在客户端环境(如 Web 应用程序)中工作并需要解析 并打印本地化的字段值。该ConversionService
提供了一个 两个 SPI 的统一类型转换 API。
在Spring MVC的特定用例中,框架本身能够在处理HTTP请求时处理简单的类型。
类型转换会根据配置的转换器集自动应用,尽管可以使用DataBinder
s 和上述格式化系统来调整该行为。请参阅相关文档。
在你处理读取和写入HTTP请求和响应正文的典型用例中,例如,当使用@RequestBody
时,Spring将使用一堆不同的预配置HttpMessageConverter
实现:实际注册的将取决于你的配置和项目中导入的库 - 比如杰克逊, 例如。我无法在文档中找到这一点,但这里是实际源代码的链接。
请考虑查看此相关SO问题,这可能会有所帮助。