当前位置: 首页 > 面试题库 >

在所有产生JSON的端点上使用@Produces(“ application / json”)是一种好习惯吗?

苏弘盛
2023-03-14
问题内容

我们开始将Jersey / JAX-RS用于内部REST端点,这些端点被我们的前端代码使用。必须返回结果的端点始终发送JSON对象。

出于调试目的,我们使用了firefox
restclient扩展。直到最近,我才输入URL并单击send,然后返回显示为JSON的内容。

但是,当我今天早上这样做时,FF扩展名又回来了,并告诉我必须将响应类型更改为二进制(BLOB)。这样做会导致显示编码的字符串而不是JSON。

我可以解决,通过设置一个请求头(Accept:application/json)。

是:可能我们应该添加@Produces("application/json")所有这些端点。

问题:真的那么简单吗?还是有充分的技术理由 这样做?


问题答案:

为了内容协商和HTTP协议正确性,您应该 始终
声明@Produces@Consumes注释(在类级别或方法级别)。没有这些注释,结果将取决于客户端请求和服务器的默认行为(在不同的实现中可能有所不同),这将导致不可预测的模棱两可的结果。

通过这些注释,我们可以 宣传
可以生产和使用的媒体类型。在获取(GET)请求时,客户端应发送一个Accept标头,其中包含他们期望返回的资源的媒体类型。并且在创建请求(PUT,POST)时,客户端应发送一个Content- Type标头,告诉服务器它们发送的数据是哪种媒体类型。如果这些标头与广告服务器要处理的标头不匹配,则客户端将收到错误响应,告诉他们问题出在哪里;如果有Retrieve请求和不匹配的Accept标头,则响应将是406
Not Acceptable。对于创建请求和不匹配的Content- Type标头,响应将为415不支持的媒体类型。

这就是内容协商的工作方式。为了确保我们的服务器行为符合客户的期望,我们应该声明我们可以在服务器上处理的内容。注释就是这样做的。

正如您提到的,当您离开时@Produces,客户端告诉您您需要更改响应类型。这是因为结果是将Content-Type响应标头设置为application/octet-stream,这就是这里的答案所得出的结论。客户端使用Content- Type标头来确定如何处理响应。

最后一个示例是针对“检索”请求的。如果我们@Consumes在“创建”端点上放弃使用,那么很多不同的事情都会出错。例如,我们有一个要接受JSON的端点,因此我们创建一个POJO来将JSON映射到。

@POST
public Response create(Customer customer) {}

为此,取决于客户端将Content- Type请求上的标头设置为application/json。但是没有@Consumes注释,我们基本上是在广告此端点以使其能够接受 任何
媒体类型,这简直是荒谬的。该@Consumes注释就像一个后卫说:“如果你不发送正确的数据类型,你可以不通过”。但是由于我们没有保护,所以所有数据都被允许通过,并且结果是不可预测的,因为取决于客户端设置的对象Content- Type,我们不知道MessageBodyReader1将处理从实体主体到的转换Customer。如果正确MessageBodyReader
如果未选择(将JSON转换为POPJO的选项),则很可能会导致异常,并且客户端将返回500 Internal Server Error,该错误与获取415
Unsupported Media Type一样不具体。

1.
请参阅Jersey文档的第8和9章。它将解释如何分别使用MessageBodyReader和将实体主体转换为Java对象(反之亦然)MessageBodyWriter



 类似资料:
  • 我们开始对前端代码使用的内部RESTendpoint使用Jersey/JAX-RS。必须返回结果的endpoint总是发送JSON对象。 出于调试目的,我们使用firefox restclient扩展。直到最近,我只需输入URL并单击send,就会得到显示为JSON的内容。 但是当我今天早上这样做的时候,FF扩展返回并告诉我必须将响应类型更改为二进制(BLOB)。这样做会导致显示编码字符串而不是J

  • 问题内容: 关于Javadoc的内容不多。(简而言之:它返回字符串的规范表示形式,从而允许使用来比较内部字符串==) 我什么时候可以使用此功能? 是否存在Javadoc中未提及的副作用,即JIT编译器或多或少的优化? 还有其他用途吗? 问题答案: 我何时会使用此函数来支持String.equals() 当你需要速度时,因为可以按引用比较字符串(==比等于快) 是否有Javadoc中未提及的副作用?

  • 问题内容: 我知道关键字存在于Java中。但是我不记得看到使用它的代码。可能我正在使用异常,并在本可以使用的地方登录。在Java中使用关键字是否是一种好习惯? 编辑 :我知道断言通常是一个好习惯。我的问题是,更准确地说,如果在Java中断言的BKM是使用关键字而不是使用异常,日志记录和其他技术。 问题答案: 不使用断言的主要原因是因为默认情况下未启用断言。因此,如果您的条件足够重要而需要断言,则不

  • 问题内容: 该方案。我在写与游戏相关的代码。在该游戏中,(同时也是一个类)具有的列表。有迹象表明,从继承其他类型的项目,例如,或。 显然,拥有我很方便。但是,当我获得玩家物品时,我唯一可以区分哪种物品的方法就是使用关键字。我确信我已经读过,依赖它是不好的做法。 在这种情况下可以使用吗?还是我应该重新考虑我的所有结构? 问题答案: 假设我正在写一些库存代码: 这样可以编译并正常工作。但是它错过了面向

  • 问题内容: 在企业应用程序中使用MS SQL Identity是否是好的做法?在创建业务逻辑以及将数据库从一个迁移到另一个时,难道不是很困难吗? 问题答案: 是的,它们工作得很好,可靠,性能最佳。与不使用身份字段相比,使用身份字段的一大好处是它们可以处理多个调用方尝试保留新ID的所有复杂的并发问题。这看起来似乎是微不足道的代码,但事实并非如此。 以下这些链接提供了一些有关身份字段以及为什么应尽可能

  • 问题内容: 我有一个枚举: 使用方法检查枚举成员之间的“层次结构” 是否存在问题?我的意思是-使用它时,除了冗长之外,还有什么缺点吗?将来有人可能会意外更改顺序。 还是做这样的事更好: 问题答案: TLDR:不,您不应该! 如果您参考javadoc中的方法: 大多数程序员都不会使用这种方法。它设计用于复杂的基于枚举的数据结构,例如和。 首先-阅读手册(在这种情况下为javadoc)。 其次-不要编