使用CDI简化JAX-RS缓存
這篇文章(通過一個簡單的示例)說明了如何使用CDI Producers使其在RESTful服務中利用緩存控制語義更加容易
 與HTTP 1.0中可用的Expires標頭相比, HTTP 1.1中添加了Cache-Control標頭,這是急需的改進。 RESTful Web服務可以利用此標頭來擴展其應用程序并使它們更有效,例如,如果您可以緩存先前請求的響應,那么顯然,如果您確定對以下內容,則無需再次向服務器發(fā)出相同的請求您緩存的數(shù)據(jù)不是陳舊的事實! 
JAX-RS有何幫助?
自其初始(1.0)版本以來, JAX-RS就已經支持Cache-Control標頭。 CacheControl類表示現(xiàn)實世界中的Cache-Control HTTP標頭,并提供了通過簡單的setter方法配置標頭的功能。 JAX-RS 2.0 javadocs中有關CacheControl類的更多信息
那么我該如何使用
只需返回一個Response對象,即可圍繞它包裝 CacheControl類的實例。
@Path("/testcache") public class RESTfulResource {@GET@Produces("text/plain")public Response find(){CacheControl cc = new CacheControl();cc.setMaxAge(20);return Response.ok(UUID.randomUUID().toString()).cacheControl(cc).build();} }盡管這對于單個方法來說相對方便,但是重復創(chuàng)建和返回CacheControl對象可能會激怒多個方法
CDI生產者來搶救!
CDI生產者可以幫助注入類的實例,這些類在技術上不是Bean (按照嚴格的定義),或者對于您無法控制的類,要使用范圍和限定符進行修飾。
這個想法是為了
- 有一個自定義注釋( @CacheControlConfig )來定義Cache-Control標頭的默認值,并在您要覆蓋它時提供靈活性 @Retention(RUNTIME) @Target({FIELD, PARAMETER}) public @interface CachControlConfig {public boolean isPrivate() default true;public boolean noCache() default false;public boolean noStore() default false;public boolean noTransform() default true;public boolean mustRevalidate() default true;public boolean proxyRevalidate() default false;public int maxAge() default 0;public int sMaxAge() default 0;}
- 只需使用CDI Producer通過使用InjectionPoint對象(由CDI高興地注入!)來創(chuàng)建CacheControl類的實例,具體取決于注釋參數(shù) public class CacheControlFactory {@Producespublic CacheControl get(InjectionPoint ip) {CachControlConfig ccConfig = ip.getAnnotated().getAnnotation(CachControlConfig.class);CacheControl cc = null;if (ccConfig != null) {cc = new CacheControl();cc.setMaxAge(ccConfig.maxAge());cc.setMustRevalidate(ccConfig.mustRevalidate());cc.setNoCache(ccConfig.noCache());cc.setNoStore(ccConfig.noStore());cc.setNoTransform(ccConfig.noTransform());cc.setPrivate(ccConfig.isPrivate());cc.setProxyRevalidate(ccConfig.proxyRevalidate());cc.setSMaxAge(ccConfig.sMaxAge());}return cc;} }
- 只需將 CacheControl實例注入您的REST資源類中,并在您的方法中使用它 @Path("/testcache") public class RESTfulResource {@Inject@CachControlConfig(maxAge = 20)CacheControl cc;@GET@Produces("text/plain")public Response find() {return Response.ok(UUID.randomUUID().toString()).cacheControl(cc).build();} }
其他想法
- 在這種情況下,產生的CacheControl實例的作用域為@Dependent,即它將與注入它的類一起生存和死亡。 在這種情況下,由于JAX-RS容器為每個客戶端請求創(chuàng)建了一個新實例,因此JAX-RS資源本身是RequestScoped (默認),因此將與每個HTTP請求一起創(chuàng)建注入的CacheControl實例的新實例。
- 您還可以引入CDI限定詞以進一步縮小范圍并考慮極端情況
- 您可能會認為,使用JAX-RS過濾器可以實現(xiàn)相同的目的。 那是正確的。 但是您需要手動設置Cache-Control標頭(在可變的MultivaluedMap中),并且邏輯不夠靈活,無法解決不同情況下的不同Cache-Control配置
實驗結果
使用NetBeans IDE播放此示例(推薦)
- 部署WAR并瀏覽到http:// localhost:8080 / JAX-RS-Caching-CDI / testcache
-  隨機字符串,將被緩存20秒 (根據(jù)@CacheControl注釋的配置) 
-  對相同URL的GET請求不會導致服務器端REST服務的調用。 瀏覽器將返回緩存的值。 
盡管代碼很簡單,但是如果您覺得很懶,可以從這里獲取(maven)項目并在其中玩轉
玩得開心!
翻譯自: https://www.javacodegeeks.com/2015/02/simplifying-jax-rs-caching-with-cdi.html
總結
以上是生活随笔為你收集整理的使用CDI简化JAX-RS缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 腾达无线路由器怎么设置拨号连接腾达路由器
- 下一篇: Maven提示:有关可执行jar的所有信
