當前位置:編程學習大全網 - 編程語言 - 如何在java REST API中用GZip和Jersey壓縮相應

如何在java REST API中用GZip和Jersey壓縮相應

有許多情景當妳的REST api提供的相應是非常長的,並且我們都知道傳遞速度和貸款在移動設備/網絡上是多重要。當開發支持REST apis的移動app的時候,我認為首要的性能最優化的點就是需要解決。猜猜是什麽?因為響應式文本,因此我們能壓縮這些文本。而且隨著當前的只能手機和平板的能力,在客戶端解壓文本應該不是個大問題...因此在這篇文章中,如果妳使用java的Jersey構建它,我將介紹妳怎麽能有選擇性的壓縮REST API響應,這個Jersey事JAX-RS的映射實現(還有更多)...

1.Jersey過濾器和攔截器

啊,感謝Jersey的強大的過濾器和攔截器特性,這個實現是相當容易的。然後過濾器是主要打算來維護像HTTP headers,URIs和/或HTTP methods的request和response的參數,攔截器是維護實體,通過維護實體的輸入/輸出流。

但是對於壓縮將使用壹個GZip WriterInterceptor,壹個寫攔截器被用於這種情況,在那個類裏,實體被寫到"wire",當在這種情況中時,它在服務器這邊,這就意味著輸出壹個響應實體。

1.1GZip Writer Interceptor

那讓我們來看看我們的GZip Writer Interceptor吧:

GZip Writer Interceptor

package org.codingpedia.demo.rest.interceptors;

import java.io.IOException;

import java.io.OutputStream;

import java.util.zip.GZIPOutputStream;

import javax.ws.rs.WebApplicationException;

import javax.ws.rs.core.MultivaluedMap;

import javax.ws.rs.ext.WriterInterceptor;

import javax.ws.rs.ext.WriterInterceptorContext;

@Provider

@Compress

public class GZIPWriterInterceptor implements WriterInterceptor {

@Override

public void aroundWriteTo(WriterInterceptorContext context)

throws IOException, WebApplicationException {

MultivaluedMap<String,Object> headers = context.getHeaders();

headers.add("Content-Encoding", "gzip");

final OutputStream outputStream = context.getOutputStream();

context.setOutputStream(new GZIPOutputStream(outputStream));

context.proceed();

}

}

註意:

它實現了WriterInterceptor,這是壹個寫攔截器的消息體的接口,這個接口包裝調用javax.ws.rs.ext.MessageBodyWriter.writeTo

供應商實現WriterInterceptor協議必須要麽以編程方式註冊進壹個JAX-RS運行環境,要麽必須用@Provider註解來註解在壹個提供商掃描語句期間自動的被JAX-RS運行環境發現。

@Compress是綁定註解的名稱,在接下來的段落中我們將更詳細的討論它

“攔截器從WriterInterceptorContext中獲得壹個輸出流並且設置壹個新的用原始的GZIP包裝器包裝的輸出流。在所有的攔截器被執行以後,輸出流最終設置WriterInterceptorContext將用於序列化實體。在上面的例子中,實體字節將被寫到GZIPOutputStream中,這個類將壓縮流數據,然後把他們寫到原始輸出流。原始流總是把數據寫到wire中。當攔截器被用在服務器上時,原始輸出流會把數據寫到底層服務器容器的流中,然後發送響應給客戶端。”

“重載方法aroundWriteTo()獲取WriterInterceptorContextz作為參數。這個上下文包括請求頭參數getters和setters,請求屬性,實體,實體流和其它屬性;當妳壓縮妳的響應時,妳應當設置'Content-Encoding'頭位gzip”

1.2 壓縮註解

過濾器和攔截器能被綁定名字。名稱綁定是壹種概念,這種概念就是允許告訴壹個JAX-RS的運行時,壹個只為特定資源方法的特定的過濾器或者攔截器將被執行。當壹個過濾器或者攔截器只對壹些特定的資源方法限制,那我們就認為它是名稱綁定。過濾器和攔截器沒有這樣的限制就被稱作global。在我們的例子中我們已經構建了@Compress註解:

Compress annotation

package org.codingpedia.demo.rest.interceptors;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import javax.ws.rs.NameBinding;

//@Compress annotation is the name binding annotation

@NameBinding

@Retention(RetentionPolicy.RUNTIME)

public @interface Compress {}

而且用它來標記在資源上的方法,這個方法應該是被壓縮的(eg:當GET-ing的時候,所有的博客用PodcastsResource)

@Compress annotation在資源方法上的使用

@Component

@Path("/podcasts")

public class PodcastsResource {

@Autowired

private PodcastService podcastService;

...........................

/*

* *********************************** READ ***********************************

*/

/**

* Returns all resources (podcasts) from the database

*

* @return

* @throws IOException

* @throws JsonMappingException

* @throws JsonGenerationException

* @throws AppException

*/

@GET

@Compress

@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })

public List<Podcast> getPodcasts(

@QueryParam("orderByInsertionDate") String orderByInsertionDate,

@QueryParam("numberDaysToLookBack") Integer numberDaysToLookBack)

throws IOException,AppException {

List<Podcast> podcasts = podcastService.getPodcasts(

orderByInsertionDate, numberDaysToLookBack);

return podcasts;

}

...........................

}

2.測試

2.1SOAPui

好了,如果妳正在用SOAPui測試,妳能使用下面的請求違反PodcastsResource

Reqest:

請求例子:

GET http://localhost:8888/demo-rest-jersey-spring/podcasts/?orderByInsertionDate=DESC HTTP/1.1

Accept-Encoding: gzip,deflate

Accept: application/json, application/xml

Host: localhost:8888

Connection: Keep-Alive

User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

Response:

被壓縮的json響應,通過SOAPui自動的解壓縮

HTTP/1.1 200 OK

Content-Type: application/json

Content-Encoding: gzip

Content-Length: 409

Server: Jetty(9.0.7.v20131107)

[

{

"id": 2,

"title": "Quarks & Co - zum Mitnehmen",

"linkOnPodcastpedia": "http://www.podcastpedia.org/quarks",

"feed": "http://podcast.wdr.de/quarks.xml",

"description": "Quarks & Co: Das Wissenschaftsmagazin",

"insertionDate": "2014-10-29T10:46:13.00+0100"

},

{

"id": 1,

"title": "- The Naked Scientists Podcast - Stripping Down Science",

"linkOnPodcastpedia": "http://www.podcastpedia.org/podcasts/792/-The-Naked-Scientists-Podcast-Stripping-Down-Science",

"feed": "feed_placeholder",

"description": "The Naked Scientists flagship science show brings you a lighthearted look at the latest scientific breakthroughs, interviews with the world top scientists, answers to your science questions and science experiments to try at home.",

"insertionDate": "2014-10-29T10:46:02.00+0100"

}

]

SOAPui接受Content-type:gzip頭,我們在GZIPWriterIntercepter中添加了並且自動的解壓了響應並且用人眼可讀的方式展示出來。

好了,就這些了。妳已經了解了Jersey如何讓它直接壓縮REST api響應了。

  • 上一篇:Gc算法編程
  • 下一篇:java中攔截器、過濾器、監聽器都有什麽區別?
  • copyright 2024編程學習大全網