如何让Spring 3.2的ConversionService和HttpMessageConverters协同工作以进行@RequestBody注释?



在 AJAX 流行之前,可以通过使用自定义属性编辑器并在控制器中注册它在 id 和实体之间进行转换。因此,如果你有一个包含CompanyUser表单支持对象,如果company.id是5,Spring将调用你的自定义属性编辑器,以便你可以获取id为5的公司并将其设置到你的user.company属性上。

现在在Ajax的做事方式中,我们有类似的要求。我们不想使用表单支持对象,而是希望将User对象作为 JSON 数据执行 HTTP POST 或 PUT 操作,并让 Spring 代表我们自动将该 JSON 转换为用户对象。Spring通过@RequestBody注解以及使用Jackson将JSON来回编组到Java对象使这成为可能。

这只是一个虚构的例子。假设一个User包含一个具有适当 getter/setter 的 Company 对象。

@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void create(@Valid @RequestBody User user) {
    userService.saveUser(user);
}

由于属性编辑器就 Spring 而言已成为过去,因此我们希望使用新的转换服务 API。对于我的应用程序,我已成功创建了一个工厂,该工厂执行我的旧属性编辑器之前执行的操作 - 将 id 转换回实体。

我的问题是,如何让 Spring 在 Jackson 封送 JSON 数据期间或之后调用转换服务?我知道可以创建自定义JsonDeserializer,但我发现编写/测试这些是一个痛苦而漫长的过程,因为我需要为大量实体执行此操作,并且每个反序列化器需要 60 到 200 行代码。

如果 Spring 可以代表我为我做 id 到实体的映射,就像它为表单支持对象所做的那样,我会很高兴。有办法吗?

它只适用于根对象User在这种情况下,它不适用于嵌套组件。Spring Data REST有一个"DomainClassConverter",你可以看看。

基本上,您要创建ConditionalGenericConverter来检查它是否可以转换请求的对象(即是否可以由EntityManager/SessionFactory加载(。(非条件版本在这里。

这一切都有点违背 REST(基本上(在服务器端进行查找,因为您应该发送请求所需的所有内容(具象状态传输和超媒体作为所有状态的传输引擎(。但那是另一个讨论:).

链接

  1. 域实体转换器博客
  2. 弹簧参考指南

Deinum先生的回答很棒。但对于实际工作,请考虑AOP;)在您的问题:)中使用它可能会很有趣。

最新更新