{"id":761,"date":"2018-02-08T16:39:51","date_gmt":"2018-02-08T14:39:51","guid":{"rendered":"http:\/\/www.loicmathieu.fr\/wordpress\/?p=761"},"modified":"2018-06-04T16:55:00","modified_gmt":"2018-06-04T14:55:00","slug":"cache-http-client-avec-cxf","status":"publish","type":"post","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/cache-http-client-avec-cxf\/","title":{"rendered":"Cache HTTP Client avec CXF"},"content":{"rendered":"<p>Dans nos applications moderne, le cache est une fonctionnalit\u00e9 technique majeur qui permet de limiter les acc\u00e8s redondant \u00e0 la m\u00eame ressources (base de donn\u00e9es, fichier, service distant HTTP, &#8230;).<\/p>\n<p>On peut impl\u00e9menter du cache \u00e0 plusieurs niveau, et g\u00e9n\u00e9ralement nos applications en utilisent sans le savoir (cache OS, cache BDD, cache applicatif de type EhCache, &#8230;) et nos browser le font aussi massivement gr\u00e2ce aux directives de cache de la sp\u00e9cification HTTP.<\/p>\n<p>Si vous avait des webservices REST d\u00e9velopp\u00e9 avec Apache CXF, vous pouvez vous aussi tirer parti simplement des directives de caches HTTP pour que les clients de vos services puissent mettre en cache les requ\u00eates \u00e0 vos services et en limiter la charge.<\/p>\n<p>Bien qu&rsquo;il existe plusieurs type de mise en cache via directives HTTP, je vais uniquement m&rsquo;attarder ici sur la directive HTTP Cache-Control : <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Cache-Contro\" rel=\"noopener\" target=\"_blank\"><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Cache-Contro\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/HTTP\/Headers\/Cache-Contro<\/a><\/a>l<\/p>\n<p>CXF n&rsquo;impl\u00e9mentant par les directives de cache HTTP et JaxRS ne contenant pas d&rsquo;annotations permettant de mettre des headers arbitraires sur une des op\u00e9rations de votre web service REST, je vais vous proposer ici une fa\u00e7on simple et \u00e9l\u00e9gante de faire.<\/p>\n<p>Pour commencer, cr\u00e9ation d&rsquo;une annotation @CacheControl qui nous permettera de sp\u00e9cifier la directive de cache que nous voudrions envoyer au client<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@Target(ElementType.METHOD )\n@Retention(RetentionPolicy.RUNTIME)\npublic @interface CacheControl {\n    String value() default \"no-cache\";\n}\n<\/pre>\n<p>Cette annotation sera ensuite utilis\u00e9e pour configurer une directive de cache HTTP sur votre service web CXF JaxRS<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n@CacheControl(\"max-age=600\")\n@GET\n@Path(\"\/person\")\npublic Person getPerson(String name) {\n    return personService.getPerson(name);\n}\n<\/pre>\n<p>Pour que cette annotation soit transform\u00e9e en header de cache par CXF, il faut impl\u00e9menter un interceptor CXF qui se chargera de r\u00e9cup\u00e9rer les informations de l&rsquo;annotations et d&rsquo;ajouter le header n\u00e9cessaire.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\npublic class CacheInterceptor extends AbstractOutDatabindingInterceptor{\n    public CacheInterceptor() {\n        super(Phase.MARSHAL);\n    }\n\n    @Override\n    public void handleMessage(Message outMessage) throws Fault {\n        \/\/search for a CacheControl annotation on the operation\n        OperationResourceInfo resourceInfo = outMessage.getExchange().get(OperationResourceInfo.class);\n        CacheControl cacheControl = null;\n        for (Annotation annot : resourceInfo.getOutAnnotations()) {\n            if(annot instanceof CacheControl) {\n                cacheControl = (CacheControl) annot;\n                break;\n            }\n        }\n\n        \/\/fast path for no cache control\n        if(cacheControl == null) {\n            return;\n        }\n\n        \/\/search for existing headers or create new ones\n        Map&lt;String, List&gt; headers = (Map&lt;String, List&gt;) outMessage.get(Message.PROTOCOL_HEADERS);\n        if (headers == null) {\n            headers = new TreeMap(String.CASE_INSENSITIVE_ORDER);\n            outMessage.put(Message.PROTOCOL_HEADERS, headers);\n        }\n\n        \/\/add Cache-Control header\n        headers.put(\"Cache-Control\", Collections.singletonList(cacheControl.value()));\n    }\n}\n<\/pre>\n<p>Pour terminer, il faut ajouter cet intercepteur \u00e0 votre server CXF, cela d\u00e9pend de la mani\u00e8re dont vous d\u00e9finissez votre serveur CXF (standalone, spring, &#8230;), plus d&rsquo;info sur les intercepteurs ici : <a href=\"http:\/\/cxf.apache.org\/docs\/interceptors.html\" rel=\"noopener\" target=\"_blank\"><a href=\"http:\/\/cxf.apache.org\/docs\/interceptors.html\">http:\/\/cxf.apache.org\/docs\/interceptors.html<\/a><\/a><\/p>\n<p>Par exemple, si vous utilisez Spring, vous pouvez ajouter les lignes suivantes \u00e0 votre fichier cxf-servlet.xml :<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n    \n    \n        \n    \n\n    <!-- other stuff goes here ... -->\n\n    \n        \n           \n\n\n\n<\/pre>","protected":false},"excerpt":{"rendered":"<p>Dans nos applications moderne, le cache est une fonctionnalit\u00e9 technique majeur qui permet de limiter les acc\u00e8s redondant \u00e0 la m\u00eame ressources (base de donn\u00e9es, fichier, service distant HTTP, &#8230;). On peut impl\u00e9menter du cache \u00e0 plusieurs niveau, et g\u00e9n\u00e9ralement nos applications en utilisent sans le savoir (cache OS, cache BDD, cache applicatif de type EhCache, &#8230;) et nos browser le font aussi massivement gr\u00e2ce aux directives de cache de la sp\u00e9cification HTTP. Si vous avait des webservices REST d\u00e9velopp\u00e9&#8230;<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/cache-http-client-avec-cxf\/\">Lire la suite<span class=\"screen-reader-text\"> Lire la suite<\/span><\/a><\/p><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[9],"tags":[160,11,159],"class_list":["post-761","post","type-post","status-publish","format-standard","hentry","category-informatique","tag-cxf","tag-java","tag-performance"],"aioseo_notices":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":64,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/convention-over-configuration\/","url_meta":{"origin":761,"position":0},"title":"convention over configuration","author":"admin","date":"mercredi 19 d\u00e9cembre 2007","format":false,"excerpt":"\"Convention over Configuration\" (on trouve parfois une traduction par \"convention plut\u00f4t que configuration), ce design pattern (ou patron de conception, pour faire plaisir aux francophones intransigeant) est un des plus int\u00e9r\u00e9ssant de ceux \u00e0 la mode en ce moment. Le principe en est tr\u00e8s simple: les applications se basent sur\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1877,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-24-quoi-de-neuf\/","url_meta":{"origin":761,"position":1},"title":"Java 24 : quoi de neuf ?","author":"admin","date":"vendredi 10 janvier 2025","format":false,"excerpt":"Maintenant que Java 24 est features complete (Rampdown Phase One au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res versions de Java, pour ceux qui\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":856,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-next\/","url_meta":{"origin":761,"position":2},"title":"Java.Next","author":"admin","date":"mercredi 31 octobre 2018","format":false,"excerpt":"Ma premi\u00e8re contribution au blog de Zenika est un article qui parle du futur (ou du pr\u00e9sent) de Java et des changements pour les d\u00e9veloppeurs dans les versions 9, 10 et 11. La gouvernance de Java y est aussi abord\u00e9. Cet article reprend et r\u00e9sume les articles que j'ai pr\u00e9c\u00e9demment\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1946,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/java-25-quoi-de-neuf\/","url_meta":{"origin":761,"position":3},"title":"Java 25 : Quoi de neuf?","author":"admin","date":"vendredi  4 juillet 2025","format":false,"excerpt":"Maintenant que Java 25 est features complete (Rampdown Phase One au jour d\u2019\u00e9criture de l\u2019article), c\u2019est le moment de faire le tour des fonctionnalit\u00e9s qu\u2019apporte cette nouvelle version, \u00e0 nous, les d\u00e9veloppeurs. Cet article fait partie d\u2019une suite d\u2019article sur les nouveaut\u00e9s des derni\u00e8res versions de Java, pour ceux qui\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1258,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/profiler-une-application-java-dans-un-conteneur-deploye-dans-kubernetes-avec-jfr-java-flight-recorder\/","url_meta":{"origin":761,"position":4},"title":"Profiler une application Java dans un conteneur d\u00e9ploy\u00e9 dans kubernetes avec JFR &#8211; Java Flight Recorder","author":"admin","date":"lundi 12 avril 2021","format":false,"excerpt":"La plupart des clients chez lesquels j'interviens aujourd'hui utilisent Kubernetes pour d\u00e9ployer leurs applications. Bien que Kubernetes soit un super outil, si on a besoin de ce type d'outil (qui est une discussion dans laquelle je ne rentrerais pas ici), il peut apporter une certaine complexit\u00e9 quant aux moyens de\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":739,"url":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/informatique\/les-optimisations-de-performances-de-java-9\/","url_meta":{"origin":761,"position":5},"title":"Les optimisations de performances de Java 9","author":"admin","date":"vendredi 26 janvier 2018","format":false,"excerpt":"Dans un pr\u00e9c\u00e9dent article sur Java 9, j'avais parcouru les principales nouveaut\u00e9s \u00e0 destination des d\u00e9veloppeurs : http:\/\/www.loicmathieu.fr\/wordpress\/informatique\/les-nouveautes-de-java-9-pour-les-developeurs. Je vais ici parcourir les principales nouveaut\u00e9s ax\u00e9es sur la performance Je vais encore reprendre les principales JEP : JEP 143: Improve Contended Locking Optimisation des monitors Java (optimisation des locks) en\u2026","rel":"","context":"Dans &quot;informatique&quot;","block_context":{"text":"informatique","link":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/category\/informatique\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/comments?post=761"}],"version-history":[{"count":0,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/posts\/761\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/media?parent=761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/categories?post=761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.loicmathieu.fr\/wordpress\/fr\/wp-json\/wp\/v2\/tags?post=761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}