【问题标题】:Why is DELETE not supported on to-many-association resources in Spring Data REST?为什么 Spring Data REST 中的多关联资源不支持 DELETE?
【发布时间】:2015-04-25 03:21:11
【问题描述】:

我正在使用 Spring Data REST。我正在尝试从实体(项目)解除集合关联。即 - 项目的属性是 List 类型。我想从该List 中删除所有项目。

为此,我使用的是 DELETE 方法:

curl -X DELETE …/categories/54ea0bcf27a2fb1b4641083a/fixedParentCategories

这给了我一个405 Method not allowed 错误代码。但是,它适用于单值关联(当它不是List 类型时)。 documentation 明确将 DELETE 列为支持的关联方法。我想知道是否有办法解决这个问题。另外,我尝试使用带有空正文的PUT (Content-Type: text/uri-list),它给出了一个关于缺少请求正文的错误。此关联上的其他操作都运行良好 - 我可以将项目添加到此集合等。

我的实体如下所示:

@Document
public class Category { 

    @DBRef(lazy = true)
    private List<Category> fixedParentCategories;
    …
}

【问题讨论】:

  • 文档还指出,对于非可选的关联返回 405。你的领域模型是什么样的?
  • @Document @Description("Category") public class Category { @Description("Fixed parent categories") @DBRef(lazy = true) private List fixedParentCategories; }
  • 在原帖中添加了域对象
  • 在测试这个时,我还观察到:- 项目(实体)上的 PUT(内容类型:应用程序/json)清除所有关联。我最终使用 PATCH 以便它们保留其价值。这是预期的吗?当然,我阅读了文档,该文档说当我只想更新请求正文 JSON 中提供的那些属性并保持其余部分不变时,我需要使用 PATCH。但这也适用于协会吗?

标签: rest spring-data spring-data-rest


【解决方案1】:

我刚刚检查了代码,您是对的,我们正在积极拒绝 DELETEMaps 和集合的请求。理由如下:

属于Map 或集合的关联在域模型中决不能是null。将其转换为 HTTP 资源意味着该资源将始终可用,并且在最坏的情况下返回一个空表示(空 JSON 数组或空 JSON 对象)。接受DELETE 请求在逻辑上将null 域模型中的关系,从而导致与第一个假设相矛盾的状态。

我们通常建议将媒体类型为text/uri-list 的空正文简单地放入关联资源以清空关联,因为这在语义上更正确。将其视为截断和删除数据库表之间的区别。

如果您认为这应该改变并且有充分的理由支持您的请求,请随时在我们的JIRA 中开票。

【讨论】:

  • 感谢您的浏览。事实上,我完全理解其中的原理,因此,我尝试将 PUT (Content-Type: text/uri-list) 与一个空正文一起使用,它给出了一个关于缺少请求正文的错误。 (这在我原来的帖子中提到过)。
  • 我添加了test cases 表明PUT 到项目资源不会擦除关联,PUT将一个空的String 添加到媒体类型为text/uri-list 擦除的关联资源协会。
  • 谢谢。测试用例很好。但是,当通过 HTTP 访问时,我仍然得到相同的响应:- { "cause": null, "message": "Required request body content is missing:" } 看起来问题出在 spring-webmvc 项目代码中。 org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodP‌​处理器.readWithMessageConverters()。这里有一个空有效载荷的检查,并抛出这个异常。通过在有效负载中发送“空格”字符来绕过此问题。然而,这是一个问题。
  • 似乎这与 Spring 4.1 稍微改变了处理空请求主体的方式有关。我已经为您归档并修复了DATAREST-485,请随时尝试快照。
  • @OliverGierke 从集合中删除单个项目怎么样?除了要删除的项目之外,我们是否应该对所有当前项目执行 PUT 请求?似乎它使客户端实现复杂化。这里的正确方法是什么?
猜你喜欢
  • 2018-09-04
  • 1970-01-01
  • 2017-04-22
  • 2014-10-08
  • 2023-03-08
  • 1970-01-01
  • 2017-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多