Java 如果@products注释丢失,jersey服务将返回什么?
我开始学习开发restful web服务 正如我在大多数示例中所注意到的,使用以下注释:Java 如果@products注释丢失,jersey服务将返回什么?,java,rest,jersey,jax-rs,restful-architecture,Java,Rest,Jersey,Jax Rs,Restful Architecture,我开始学习开发restful web服务 正如我在大多数示例中所注意到的,使用以下注释: @Consumes 定义输入参数的格式 @Produces 定义输出参数的格式 @Produces 但在实际代码中,我看到的方法如下所示: @POST @Consumes(MediaType.APPLICATION_FORM_URLENCODED) @Path("/login") public Response login(@FormParam("login") final String userna
@Consumes
定义输入参数的格式
@Produces
定义输出参数的格式
@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
将根据@消费(MediaType.APPLICATION\u form\u URLENCODED)
生成表单。我看到了执行这个方法的URL
但我不明白这个方法会返回什么。哪种格式?默认情况下,如果未指定,Jersey将生成“应用程序/八位字节流”。有关详细信息,请参阅。它返回Response对象,其中包含您希望回复客户端的http状态。我只想澄清,“默认情况下,Jersey生成”应用程序/八位字节流“如果未指定”并不完全正确。实际上,幕后有很多复杂的事情,这决定了最终的
内容类型。如规范所述:
请注意,当无法确定具体类型时,上面(实际上在下面:-)使用默认媒体类型application/octetstream
呈现响应
但是,正如我所说,有一个复杂的算法用于确定这种“具体类型”。我测试过的案例中没有多少会返回application/octet-stream
。它如下所示(这是直接从规范中获得的。您可以尝试了解它的正面或反面,但它不适合外行):
3.8确定响应的媒体类型
在许多情况下,无法静态确定响应的介质类型。以下算法用于在运行时确定响应媒体类型Mselected:
如果该方法返回其元数据包含响应媒体类型的Response
实例
(msspecified)然后设置Mselected=msspecified,finish
收集可生产介质类型集p:
- 如果方法用
@products
注释,则设置P={V(method)},其中V(t
)表示指定目标t
上@products
的值
- 否则,如果用
@products
注释该类,则设置P={V(class)}
- Else set P={V(writers)},其中“
writers
”是支持返回的实体对象类的MessageBodyWriter
的集合
如果p={},则设置p={'*/*'
}
获取可接受的媒体类型A。如果A={},则设置A={'*/*'
}
设置M={}。适用于一个组织的每个成员<代码>a
:
- 对于P的每个成员<代码>p:
- 如果a与
兼容,则将S(p
;a
)添加到M,其中函数p
返回对中最具体的媒体类型,q值为S
,服务器端qs值为a
p
NotAcceptableException
(406状态)且无实体。必须按照第3.3.4节所述处理例外情况。结束(n/M>n/*>*/*)
,次键为q值,第三键为qs值- 如果
是具体类型,则设置Mselected=m
,finishm
'*/*'
或'application/*
',则设置Mselected='application/octet stream'
,完成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();
}
以上内容将返回内容类型: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();
}
根据我测试的结果,它将返回内容类型:application/xml
,是的,主体内容将是xml
现在,如果我们使用application/json
的Accept
头发送请求,我们将得到Content-Type:application/json
的响应头,因为是的,主体内容将是json。这是内容协商发挥作用的一个因素
如果我们只是用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();
}
由于没有内容,因此将不会有内容类型
响应标题
现在,上面的一些示例不是great REST princial示例,但它表明,如果我们不显式地使用@products
设置媒体类型,那么在确定媒体类型方面需要做很多工作。你必须考虑,响应的身体,可用代码<代码> MeasAgBoDyDrase<代码>,你必须考虑到,从MUBO巨无霸的任何其他方面来看。(注意:我将“内容协商”链接加粗,因为这是一个在使用REST时应该非常熟悉的概念。它实际上在JAX-RS/Jersey中起着重要作用)
因此,您的问题的答案实际上是这取决于。但希望您已经从这篇文章中获得了一些额外的知识:-)正确的url现在是“如果请求不包含内容类型头,那么使用应用程序/octet流媒体类型。”