jax-rs jax-ws_使用JAX-RS的HTTP缓存
jax-rs jax-ws
在上一個博客中,我們討論了不同類型的緩存及其用例。
在本文中,我們將探討如何利用HTTP響應(yīng)標頭和JAX-RS提供的支持來利用緩存。
過期標題
在HTTP 1.0中,一個名為Expires的簡單響應(yīng)頭將告訴瀏覽器它可以緩存對象或頁面多長時間。 在將來的某個日期之后,緩存將無效。 因此,如果我們進行API調(diào)用以檢索數(shù)據(jù):
響應(yīng)頭為:
HTTP/1.1 200 OK Content-Type: application/xml Expires: Tue, 25 Aug 2013 16:00 GMT ----- <user id="1">...</users>這表示XML數(shù)據(jù)的有效期至格林尼治標準時間2013年8月25日16:00。
JAX-RS在javax.ws.rs.core.Response對象中支持此標頭。
@Path("{id}")@GET@Produces(MediaType.APPLICATION_XML)public Response getUserXML(@PathParam("id") Long id){User user = userDB.get(id);ResponseBuilder builder = Response.ok(user,MediaType.APPLICATION_XML);//Putting expires header for HTTP broswer caching.Calendar cal = Calendar.getInstance();cal.set(2013,7,25,16,0);builder.expires(cal.getTime());return builder.build();}但是,為了支持CDN,代理緩存和重新驗證,需要具有功能更豐富,控件更明確的增強頭。 因此,在HTTP 1.1中,引入了一些新的標頭,并對Expires進行了描述。 讓我們探索它們。
緩存控制
Cache-Control有一組可變的逗號分隔指令,用于定義誰可以緩存,緩存方式和緩存時間。 讓我們探索其中的幾個:
- – private / public :這是可訪問性指令,private表示瀏覽器可以緩存對象,但是代理或CDN不能,而public則使所有人均可訪問。
- -沒有緩存,沒有存儲,最大使用年齡 ,只有幾個名字能說明問題。
JAX-RS提供javax.ws.rs.core.CacheControl類來表示此標頭。
@Path("{id}")@GET@Produces(MediaType.APPLICATION_XML)public Response getUserXMLwithCacheControl(@PathParam("id") Long id){User user = userDB.get(id);CacheControl cc = new CacheControl();cc.setMaxAge(300);cc.setNoStore(true);cc.setPrivate(true);ResponseBuilder builder = Response.ok(user,MediaType.APPLICATION_XML);builder.cacheControl(cc);return builder.build();}重新驗證和條件GET :緩存過期后,緩存器可以重新驗證緩存,向服務(wù)器發(fā)送請求以檢查緩存是否陳舊或保持良好狀態(tài)。 這是通過名為“ Last-Modified ”的標頭完成的。
HTTP/1.1 200 OK .... Cache-Control: max-age=1000 Last-Modified: Mon, 19 aug 2013 16:00 IST要重新驗證,必須發(fā)送帶有標頭“ If-modified-since ”的GET請求。這稱為條件GET,如果數(shù)據(jù)被修改,則將發(fā)送具有當前資源值的響應(yīng)代碼200(OK)。 如果未修改數(shù)據(jù),則發(fā)送響應(yīng)代碼“ 304”,這表示高速緩存仍然有效,此時可以更新“上次修改”標簽。
埃塔格
Etag是另一個HTTP標頭,可用于重新驗證緩存,它通常是MD5哈希值。 服務(wù)器將響應(yīng)中從資源生成的哈希作為Etag值發(fā)送,以便在驗證時,客戶端可以將其Etag值發(fā)送給服務(wù)器,以檢查駐留在服務(wù)器上的值是否匹配。(由于哈希是從資源生成的,因此請更改資源中會生成不同的哈希值)
對于此條件GET,發(fā)送帶有標頭“ If-none-Match”的請求以進行驗證。
GET /users/23 HTTP/1.1 If-None-Match: "23432423423454654667444"此外,根據(jù)不同的用例,我們可以具有強弱的Etag值。
JAX-RS為我們提供了相同的javax.ws.rs.core.EntityTag。
public class EntityTag { ..... .....為了幫助有條件的GET,JAX-RS還提供了一個可注入的幫助程序類Request,該類具有以下方法:
.... ResponseBuilder evalutatePostConditions(EntityTag eTag); ResponseBuilder evaluatePreConditions(Date isLastModified); .....比較請求標頭中發(fā)送的etag或LastModified值。 讓我們看一個例子……
@Path("{id}")@GET@Produces(MediaType.APPLICATION_XML)public Response getUserWithEtagSupport(@PathParam("id") Long id,@Context Request request){User user = userDB.get(id);//generating Etag out of hashCode of userEntityTag tag = new EntityTag(Integer.toString(user.hashCode()));CacheControl cc = new CacheControl();cc.setMaxAge(1000);ResponseBuilder builder = request.evaluatePreconditions(tag);if(builder!=null){//means the preconditions have been met and the cache is valid//we just need to reset the cachecontrol max age (optional)builder.cacheControl(cc);return builder.build();}//preconditions are not met and the cache is invalid//need to send new value with reponse code 200 (OK)builder = Response.ok(user,MediaType.APPLICATION_XML);//reset cache control and eTag (mandatory)builder.cacheControl(cc);builder.tag(tag);return builder.build();}如果滿足條件,則返回空值,這意味著最新標記和請求標頭中提供的標記匹配,并且無需發(fā)送響應(yīng)為OK的新數(shù)據(jù)。 發(fā)送“ 304”響應(yīng),表示未修改。
如果標簽不匹配,則返回一個新的RequestBuilder對象,在其中設(shè)置新的etag和當前數(shù)據(jù)版本(在這種情況下為用戶)。
這就是使用JAX-RS可以有效利用HTTP緩存發(fā)揮其全部潛力的方式。
翻譯自: https://www.javacodegeeks.com/2013/10/http-caching-using-jax-rs.html
jax-rs jax-ws
總結(jié)
以上是生活随笔為你收集整理的jax-rs jax-ws_使用JAX-RS的HTTP缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在Microsoft Azure上运行E
- 下一篇: 鬼最怕的七种人 分别是哪几种