如果缺少@Produces注释,球衣服务会返回什么?

时间:2014-12-18 10:20:04

标签: java rest jersey jax-rs restful-architecture

我开始学习用于开发宁静网络服务的球衣。

正如我在大多数示例中所注意到的那样使用以下注释:

@Consumes

定义输入参数的格式

@Produces

定义输出参数的格式

但在实际代码中我看到的方法如下:

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/login")
public Response login(@FormParam("login") final String username, @FormParam("password") final String password){...}

我看到此方法使用POST HTTP方法。参数userNamepassword的格式为@Consumes(MediaType.APPLICATION_FORM_URLENCODED)。我看到URL来执行这个方法。

但是我不明白这个方法会返回什么。哪种格式?

2 个答案:

答案 0 :(得分:6)

我只想澄清"默认泽西岛产生"应用程序/八位字节流"如果未指定" 并非完全正确。实际上幕后有很多复杂性,这决定了最终的Content-Type。如规范中所述:

  

请注意,当无法确定具体类型时,上述(实际以下 :-)会呈现默认媒体类型为application/octetstream 的响应。< / p>

但是,就像我说的那样,有一个复杂的算法用于确定这个&#34;具体类型&#34;。我测试过的案例并不多,会返回application/octet-stream。它如下(这是直接来自规范。你可以尝试制作它的头或尾,但它不适合外行):

  

3.8确定响应的MediaType

     

在许多情况下,无法静态确定响应的媒体类型。以下算法用于在运行时确定响应媒体类型,M selected

     
      
  1. 如果方法返回Response的实例,其元数据包含响应媒体类型   ( M 指定)然后设置 M selected = M 指定< / sub>,完成。

  2.   
  3. 收集可生成的媒体类型 P

         
        
    • 如果方法使用@Produces进行注释,请设置 P = { V (方法)}其中 V ({{ 1}})表示指定目标t上的@Produces的值。
    •   
    • 如果该类使用t注释,则设置 P = {V(class)}。
    •   
    • 其他设置 P = { V (作家)}其中&#39; @Produces&#39;是支持返回的实体对象的类的writers集。
    •   
  4.   
  5. 如果 P = {},请设置 P = {MessageBodyWriter}

  6.   
  7. 获取可接受的媒体类型 A 。如果 A = {},请设置 A = {'*/*'}

  8.   
  9. 设置 M = {}。对于 A 的每个成员; '*/*'

         
        
    • 对于 P 的每个成员; a:   
          
      1. 如果a与p兼容,请将 S p; a)添加到 M ,其中函数{ {1}}返回该对中最具体的媒体类型,其q值为p,服务器端qs值为S
      2.   
    •   
  10.   
  11. 如果 M = {},则生成a(406状态)且无实体。必须按照第3.3.4节中的描述处理异常。完成。

  12.   
  13. 按降序排序 M ,主键为p,q值为二级密钥,qs值为三级键。

  14.   
  15. 对于 M 的每个成员; NotAcceptableException

         
        
    • 如果(n/m > n/* > */*)是具体类型,请设置 M selected = m,完成。
    •   
  16.   
  17. 如果 M 包含mm&#39;,请设置 M selected = '*/*',完成。

  18.   
  19. 生成'application/*(406状态)且无实体。必须按照第3.3.4节中的描述处理异常。完成。

  20.   

您可以看到它并不像说它始终默认为'application/octet-stream'那么容易。简单的例子

NotAcceptableException

以上内容将返回application/octet-stream

假设您创建了一个@POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response createCustomer(@FormParam("id") int id, @FormParam("name") String name) { return Response.ok("OK I GOT IT").build(); } 对象并将其返回

Content-Type: text/plain

根据我测试的内容,它将返回Customer,是的,正文内容为xml。

现在,如果我们使用@POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response createCustomer(@FormParam("id") int id, @FormParam("name") String name) { Customer customer = new Customer(id, name); return Response.ok(customer).build(); } Content-Type: application/xml标头发送请求,我们将获得Accept的响应标头,因为正文内容将是json。这是内容协商起因的一个因素

如果我们只回复了application/json,这在Content-Type: application/json /创建请求中非常常见

201 Created

将会有没有 POST响应标头,因为没有内容。

现在上面的一些示例并不是很好的REST原理示例,但它表明,如果我们没有明确地将其设置为{{1 }}。你必须考虑,响应的主体,@POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) public Response createCustomer(@FormParam("id") int id, @FormParam("name") String name) { return Response.created(someNewUri).build(); } ,你有Content Negotiation因素,以及该规范中那个mumbo-jumbo中的其他内容。 (注意:我已经加强了内容协商和链接,因为这是一个在使用REST时应该熟悉的概念。它实际上对JAX-RS / Jersey起了很大的作用。) / p>

所以你问题的答案真的是取决于。但希望你从这篇文章中获得了一些额外的知识:-)

答案 1 :(得分:2)

默认泽西岛生产&#34; application / octet-stream&#34;如果没有指定。有关详细信息,请参阅this。它返回Response对象,其中包含您希望回复客户端的http状态。