我开始学习用于开发宁静网络服务的球衣。
正如我在大多数示例中所注意到的那样使用以下注释:
@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方法。参数userName
和password
的格式为@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
。我看到URL来执行这个方法。
但是我不明白这个方法会返回什么。哪种格式?
答案 0 :(得分:6)
我只想澄清"默认泽西岛产生"应用程序/八位字节流"如果未指定" 并非完全正确。实际上幕后有很多复杂性,这决定了最终的Content-Type
。如规范中所述:
请注意,当无法确定具体类型时,上述(实际以下 :-)会呈现默认媒体类型为
application/octetstream
的响应。< / p>
但是,就像我说的那样,有一个复杂的算法用于确定这个&#34;具体类型&#34;。我测试过的案例并不多,会返回application/octet-stream
。它如下(这是直接来自规范。你可以尝试制作它的头或尾,但它不适合外行):
3.8确定响应的MediaType
在许多情况下,无法静态确定响应的媒体类型。以下算法用于在运行时确定响应媒体类型,M selected :
如果方法返回
Response
的实例,其元数据包含响应媒体类型 ( M 指定)然后设置 M selected = M 指定< / sub>,完成。收集可生成的媒体类型 P :
- 如果方法使用
@Produces
进行注释,请设置 P = { V (方法)}其中 V ({{ 1}})表示指定目标t
上的@Produces
的值。- 如果该类使用
t
注释,则设置 P = {V(class)}。- 其他设置 P = { V (作家)}其中&#39;
@Produces
&#39;是支持返回的实体对象的类的writers
集。如果 P = {},请设置 P = {
MessageBodyWriter
}获取可接受的媒体类型 A 。如果 A = {},请设置 A = {
'*/*'
}设置 M = {}。对于 A 的每个成员;
'*/*'
:
- 对于 P 的每个成员;
a
:
- 如果a与
p
兼容,请将 S (p
;a
)添加到 M ,其中函数{ {1}}返回该对中最具体的媒体类型,其q值为p
,服务器端qs值为S
。如果 M = {},则生成
a
(406状态)且无实体。必须按照第3.3.4节中的描述处理异常。完成。按降序排序 M ,主键为
p
,q值为二级密钥,qs值为三级键。对于 M 的每个成员;
NotAcceptableException
:
- 如果
(n/m > n/* > */*)
是具体类型,请设置 M selected =m
,完成。如果 M 包含
m
或m
&#39;,请设置 M selected ='*/*'
,完成。- 醇>
生成
'application/*
(406状态)且无实体。必须按照第3.3.4节中的描述处理异常。完成。
您可以看到它并不像说它始终默认为'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状态。