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

gst*_*low 3 java rest jax-rs jersey restful-architecture

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

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

@Consumes
Run Code Online (Sandbox Code Playgroud)

定义输入参数的格式

@Produces
Run Code Online (Sandbox Code Playgroud)

定义输出参数的格式

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

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

我看到这个方法使用POSTHTTP方法.参数userNamepassword将具有形式 @Consumes(MediaType.APPLICATION_FORM_URLENCODED).我看到URL来执行这个方法.

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

Pau*_*tha 7

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

请注意,上面(实际上在下面 :-)用application/octetstream 无法确定具体类型的默认媒体类型呈现响应.

但是,正如我所说,有一个复杂的算法可用于确定这种"具体类型".并且我测试过的案例并不多application/octet-stream.它如下(这是直接来自规范.你可以尝试制作它的头或尾,但它不适合外行):

3.8确定响应的MediaType

在许多情况下,不可能静态地确定响应的媒体类型.以下算法用于确定在运行时选择的响应媒体类型:

  1. 如果该方法返回Response其元数据的实例包括响应媒体类型(M 指定),则设置M selected = M 指定,完成.

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

    • 如果方法使用注释@Produces,则设置P = { V(方法)},其中V(t)表示@Produces指定目标上的值t.
    • 否则,如果类使用注释@Produces,则设置P = {V(class)}.
    • 否则设置P = { V(writers)}其中' writers'是MessageBodyWriter支持返回实体对象的类的集合.
  3. 如果P = {},则设置P = { '*/*'}

  4. 获得可接受的媒体类型.如果A = {},请设置A = { '*/*'}

  5. 设置M = {}.对于A的每个成员; a:

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

  7. 按降序排序M,具有特定(n/m > n/* > */*)的主键,q值的辅助键和qs值的三级键.

  8. 对于M的每个成员; m:

    • 如果m是具体类型,则设置M selected = m,完成.
  9. 如果M包含'*/*''application/*',设置M 选择 = 'application/octet-stream',则完成.

  10. 生成NotAcceptableException(406状态),没有实体.必须按照第3.3.4节中的描述处理异常.完.

你可以看到它并不像说它总是默认的那么容易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();
}
Run Code Online (Sandbox Code Playgroud)

以上将返回 Content-Type: text/plain

假设您创建一个Customer对象并将其返回

@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();
}
Run Code Online (Sandbox Code Playgroud)

根据我的测试,它将返回Content-Type: application/xml,是的,身体内容是xml.

现在,如果我们发送带有Accept标头的请求application/json,我们将获得响应标头Content-Type: application/json,因为正文内容将是json.这是内容协商的一个因素

如果我们只是用a响应201 Created,这在POST/ create请求中很常见

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response createCustomer(@FormParam("id") int id, 
                               @FormParam("name") String name) {
    return Response.created(someNewUri).build();
}
Run Code Online (Sandbox Code Playgroud)

会有没有 Content-Type响应头,因为没有内容.

现在,上面的一些示例并不是很好的REST原理示例,但是它表明,如果我们没有明确地设置它,那么确定媒体类型有很多@Produces.您必须考虑,响应的主体,可用MessageBodyWriters,您有内容协商要素,以及该规范中那个mumbo-jumbo中的其他内容.(注意:我已经加入了"内容协商"链接,因为这是一个在使用REST时应该熟悉的概念.它实际上与JAX-RS/Jersey有很大关系).

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