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響應了。