java - 在所有生成 JSON 的端点上使用 @Produces("application/json") 是一种好习惯吗?
问题描述
我们开始将 Jersey/JAX-RS 用于我们的前端代码使用的内部 REST 端点。必须返回结果的端点总是发送 JSON 对象。
出于调试目的,我们使用了 firefox restclient扩展。直到最近,我只是输入 URL 并点击发送,然后将返回显示为 JSON 的内容。
但是当我今天早上这样做时,FF 扩展又回来了,告诉我必须将响应类型更改为二进制 (BLOB)。这样做会导致显示编码字符串而不是 JSON。
我可以通过设置请求标头(Accept:
to be application/json
)来解决这个问题。
做一些更多的研究,我遇到了这个问题。我的结论是:也许我们应该添加@Produces("application/json")
到所有这些端点。
问题:真的那么简单,还是有充分的技术理由不这样做?
解决方案
出于内容协商和 HTTP 协议正确性的目的,您应该始终声明@Produces
和@Consumes
注释(在类级别或方法级别) 。如果没有这些注释,结果将取决于客户端请求和服务器的默认行为(在不同的实现中可能会有所不同),这会导致不可预测和模棱两可的结果。
通过这些注释,我们可以宣传我们可以生产和消费的媒体类型。在检索 (GET) 请求中,客户端应发送一个Accept
标头,其中包含他们期望返回的资源的媒体类型。在创建请求(PUT、POST)上,客户端应该发送一个Content-Type
标头,告诉服务器他们正在发送的数据是什么媒体类型。如果这些标头与服务器宣传要处理的标头不匹配,那么客户端将收到错误响应,告诉他们问题所在;使用 Retrieve 请求和不匹配的Accept
标头,响应将是406 Not Acceptable。使用 Create 请求和不匹配的Content-Type
标头,响应将是415 Unsupported Media Type。
这就是内容协商的工作原理。并且为了确保我们的服务器按照客户期望的方式运行,我们应该声明我们可以在服务器上处理什么。注释就是这样做的。
正如您所提到的,当您离开时@Produces
,客户告诉您需要更改响应类型。这是因为结果是Content-Type
响应标头设置为application/octet-stream
,这就是这里的答案得出的结论。客户端使用Content-Type
标头来确定如何处理响应。
最后一个示例是针对检索请求的。如果我们@Consumes
在 Create 端点上省略了,很多不同的事情都可能出错。举个例子,我们有一个我们想要接受 JSON 的端点,所以我们创建一个 POJO 来将 JSON 映射到。
@POST
public Response create(Customer customer) {}
为此,它取决于客户端将Content-Type
请求的标头设置为application/json
. 但是如果没有@Consumes
注释,我们基本上是在宣传这个端点能够接受任何媒体类型,这太荒谬了。注释就像一个守卫说“@Consumes
如果你不发送正确类型的数据,你就不能通过”。但是由于我们没有守卫,所以所有数据都被允许通过,并且结果是不可预测的,因为根据客户端设置的Content-Type
to,我们不知道MessageBodyReader
1将处理从实体主体到的转换Customer
。如果正确MessageBodyReader
未选择(将 JSON 转换为 POPJO 的那个),那么它很可能会导致异常,并且客户端将返回 500 Internal Server Error,这不像获取 415 Unsupported Media Type 那样具体。
1.参见 Jersey 文档的第 8 章和第 9 章。它将解释实体主体如何分别使用MessageBodyReader
和转换为 Java 对象(反之亦然) 。MessageBodyWriter
推荐阅读
- firebase - 在 FireStore / Document DB 中有效地存储和获取喜欢
- c# - 仅将行添加到一组数据网格列,其他列应保持不变
- python - 在朱利安日期python中创建日期范围
- authentication - 使用私钥取消 JSch Auth
- javascript - 仅使用 JQuery 更改同一 div 组的同级输入
- oracle - ORA-29024 证书验证失败
- java - DebugView 没有可用的设备
- django - django rest框架创建json和csv api
- ansible - Ansible 遍历数组并使用过滤器
- php - PHPWord 树枝与 css 到 word