spring丶@produces注解-作用解答

----我理解的是转换返回数据的格式,也就是 返回的内容类型 ----

----注:@consumes是指定处理请求的提交内容类型。两者刚好相反----

注解@Produces用于定义方法的响应实体的数据类型,可以定义一个或多个,同时可以为每种类型定义质量因素(qualityfactor)。

质量因素是取值范围从0到1的小数值。如果不定义质量因素,那么该类型的质量因素默认为1。

我们将结合示例深入了解@Produces注解对媒体类型的影响,示例代码如下。

 
 
  1. @Path("conneg-resource")  
  2. public class ConnegResource {  
  3.   @GET  
  4.   @Path("{id}")  
  5.   //关注点1:媒体类型为XML  
  6.   @Produces(MediaType.APPLICATION_XML)  
  7.   public Book getJaxbBook(@PathParam("id") final Long bookId) {  
  8.       return new Book(bookId);  
  9.   }  
  10.  
  11.   @GET  
  12.   @Path("{id}")  
  13.   //关注点2:媒体类型为JSON  
  14.   @Produces(MediaType.APPLICATION_JSON)  
  15.   public Book getJsonBook(@PathParam("id") final Long bookId) {  
  16.       return new Book(bookId);  
  17.   }  

在这段代码中,getJaxbBook()和getJsonBook()是同等质量因素、资源地址相同的两个GET方法,一个定义响应实体格式为XML,

一个定义响应实体格式为JSON,见关注点1和2。那么对同一个资源的访问,JAX-RS2该如何选择处理方法呢?

如果请求中明确定义可接受的数据类型为两者之一,处理方法应该是定义相应数据类型的方法。如果两者都定义了,

处理方法应该是质量因素高的方法。如果两者都定义,而且数据类型的质量因素是相等的或者没有定义Accept,XML的方法会被优先选择。

客户端明确表述格式为XML,Jersey通过内容协商,会选择getJaxbBook()作为相应的资源方法来处理该请求。其测试代码如下所示。

 
 
  1. WebTarget path = target("conneg-resource").path("123");  
  2. Builder request = path.request(MediaType.APPLICATION_XML_TYPE);  
  3. Book book = request.get(Book.class);  
  4.  
  5. > GET http://localhost:9998/conneg-resource/123  
  6. > Accept: application/xml  
  7. < Content-Type: application/xml  
  8. <?xml version="1.0" encoding="UTF-8" standalone="yes"?><book bookId="123"/> 

接下来,测试一个稍微复杂的内容协商。客户端明确表述格式的质量因素JSON高于XML,Jersey会选择资源方法getJsonBook()来处理请求。

示例代码如下所示。

 
 
  1. WebTarget path = target("conneg-resource").path("123");  
  2. Builder request = path.request();  
  3. request.header("Accept", "application/xml;q=0.1,application/json;q=0.2");  
  4. Book book = request.get(Book.class);  
  5. ...1 > GET http://localhost:9998/conneg-resource/123 1 > Accept: application/xml;q=0.1,application/json;q=0.2 2 < Content-Type: application/json {"bookId":123} 

现在我们清楚了两个同等方法的场景,再来看一个方法中多种数据类型的场景。示例代码如下。

 
 
  1. ...java  
  2. @GET  
  3. @Produces({ "application/json; qs=.9", "application/xml; qs=.5" })  
  4. @Path("book/{id}")  
  5. public Book getBook(@PathParam("id") final Long bookId) {  
  6.     return new Book(bookId);  

在这段代码中,getBook()方法定义了XML和JSON两种表述数据类型,XML的质量因素是0.5(0可以省略),JSON的是0.9。

因此,可以推断,如果客户端请求中,明确接收的数据类型是两者之一,响应实体使用指定类型。

如果没有定义或者两者都定义且JSON的质量因素大于或者等于XML,则返回JSON类型。

还有一种用例是,两者都定义但JSON的质量因素小于XML,该如何处理请求方法呢?

答案是:内容协商的结果按照客户端的喜好选择响应实体的数据类型,即选择XML格式。

其测试代码如下所示,客户端明确表述格式XML优于JSON,虽然服务器端定义的资源方法中JSON的质量因素高,

但Jersey会根据客户端的喜好,选择了XML格式作为表述的格式返回。

 
 
  1. WebTarget path = target("conneg-resource").path("book").path("123");  
  2. Builder request = path.request();  
  3. request.header("Accept", "application/xml;q=0.7,application/json;q=0.2");  
  4. Book book = request.get(Book.class);  
  5.  
  6. > GET http://localhost:9998/conneg-resource/book/123  
  7. > Accept: application/xml;q=0.7,application/json;q=0.2  
  8. < Content-Type: application/xml  
  9. <?xml version="1.0" encoding="UTF-8" standalone="yes"?><book bookId="123"/> 


转载自:http://book.51cto.com/art/201701/529132.htm

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值