使用JAX-RS的HTTP缓存
在上一個博客中,我們討論了不同類型的緩存及其用例。
在本文中,我們將探討如何利用HTTP響應(yīng)標(biāo)頭和JAX-RS提供的支持來利用緩存。
過期標(biāo)題
在HTTP 1.0中,一個名為Expires的簡單響應(yīng)頭將告訴瀏覽器它可以緩存對象或頁面多長時間。 在將來的某個日期之后,緩存將無效。 因此,如果我們進(jìn)行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資料的有效期至格林尼治標(biāo)準(zhǔn)時間2013年8月25日16:00。
JAX-RS在javax.ws.rs.core.Response對象中支持此標(biāo)頭。
@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,代理緩存和重新驗證,需要具有功能更豐富,具有更明確控件的增強(qiáng)標(biāo)題。 因此,在HTTP 1.1中,引入了一些新的標(biāo)頭,并對Expires進(jìn)行了描述。 讓我們探索它們。
緩存控制
Cache-Control有一組可變的逗號分隔指令,用于定義誰,如何以及可以緩存多長時間。 讓我們探索其中的幾個:
- – private / public :這是可訪問性指令,private表示瀏覽器可以緩存對象,但代理或CDN不能,而public則使所有人均可訪問。
- -無緩存,無存儲,最大使用期限-很少有人用名字講述故事。
JAX-RS提供javax.ws.rs.core.CacheControl類來表示此標(biāo)頭。
@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 ”的標(biāo)頭完成的。
HTTP/1.1 200 OK .... Cache-Control: max-age=1000 Last-Modified: Mon, 19 aug 2013 16:00 IST要重新驗證,必須發(fā)送帶有標(biāo)頭“ If-modified-since ”的GET請求。這稱為條件GET,如果數(shù)據(jù)被修改,則將發(fā)送具有當(dāng)前資源值的響應(yīng)代碼200(OK)。 如果未修改數(shù)據(jù),則發(fā)送響應(yīng)代碼“ 304”,這表示高速緩存仍然有效,此時可以更新“上次修改”標(biāo)簽。
埃塔格
Etag是另一個HTTP標(biāo)頭,可用于重新驗證緩存,它通常是MD5哈希值。 服務(wù)器將響應(yīng)中從資源生成的哈希作為Etag值發(fā)送,以便在驗證時,客戶端可以將其Etag值發(fā)送給服務(wù)器以檢查駐留在服務(wù)器上的值是否匹配。(由于哈希是從資源生成的,因此請更改資源中會生成不同的哈希值)
對于此條件GET,發(fā)送帶有標(biāo)頭“ If-none-Match”的請求以進(jìn)行驗證。
GET /users/23 HTTP/1.1 If-None-Match: "23432423423454654667444"此外,根據(jù)不同的用例,我們可以具有強(qiáng)弱的Etag值。
JAX-RS為我們提供了相同的javax.ws.rs.core.EntityTag。
public class EntityTag { ..... .....為了幫助有條件的GET,JAX-RS還提供了一個可注入的幫助程序類Request,它具有以下方法:
.... ResponseBuilder evalutatePostConditions(EntityTag eTag); ResponseBuilder evaluatePreConditions(Date isLastModified); .....比較請求標(biāo)頭中發(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();}如果滿足條件,則返回空值,這意味著最新標(biāo)記和請求標(biāo)頭中提供的標(biāo)記匹配,并且無需發(fā)送響應(yīng)為OK的新數(shù)據(jù)。 發(fā)送“ 304”響應(yīng),表示未修改。
如果標(biāo)簽不匹配,則返回一個新的RequestBuilder對象,在其中設(shè)置新的etag和當(dāng)前數(shù)據(jù)版本(在這種情況下為用戶)。
這就是使用JAX-RS可以有效利用HTTP緩存發(fā)揮其全部潛力的方式。
翻譯自: https://www.javacodegeeks.com/2013/10/http-caching-using-jax-rs.html
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的使用JAX-RS的HTTP缓存的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是显性突变什么是隐性突变 什么是显性
- 下一篇: 休眠中的自然身份证