5.FreshMinutes.IT – Java & IT

5 minutes pour consolider ses connaissances en Java et dans les Nouvelles Technos.
  • Accueil
  • À propos
  • Contact, Twitter, Tumblr & Buzz

Gérer le Cache-Control HTTP dans une application Web Java EE avec Tomcat

Eric Vialle | Lundi 15 février 2010 | 9:15


Dans cet article, nous allons voir comment optimiser encore plus le temps de chargement de vos applications/pages web grâce à Cache-Control. Le Cache-Control est en-tête du protocole HTTP (protocole utilisé par un navigateur et un serveur web pour communiquer, entre autres). Cet en-tête permet de demander à un navigateur web de place dans sa mémoire un fichier, afin d’éviter que celui-ci le re-telecharge à chaque fois du serveur. Comme à notre habitude, nous verrons cela en deux temps: d’abord l’explication du Cache-Control dans le protocole HTTP, puis son implémentation dans une application web Java EE. Nous verrons deux façons de faire, la voie simple avec juste un petit réglage et une amorce vers un réglage plus fin, en utilisant un Listener.

Les En-Tête de gestion de Cache dans le protocole HTTP

Le champ Cache-Control a la forme: Cache-Control: attribute=value. Les attributs possibles sont assez nombreux. Nous utiliserons ici l’attribut max-age. Cet attribut prend comme valeur la durée de vie maximale en cache du fichier, en secondes.

Il existe beaucoup d’attributs pour Cache-Control, Wikipedia offre une très bonne liste de ces attributs et des valeurs possibles.


Exemple de requêtes HTTP contenant Cache-Control


The Easy Way: configurer uniquement web.xml

Si vous avez besoin d’un réglage assez peu fin, vous pouvez utiliser le réglage intégré à Tomcat et à tout bon conteneur web. Dans le fichier web.xml, il suffit d’ajouter cette balise afin d’ajouter une expiration pour le cache:

<web-app id='myId'>

  <cache-mapping url-regexp=''
                 expires='10'/>
<!-- ou bien -->
<cache-mapping url-pattern='*.jpg'
                 expires='15m'/>

</web-app>

Le suffixe de expires définit l’unité de temps:

  • s: secondes
  • m: minutes
  • h: heure
  • D: jours

Je dois vous avouer qu’avec cette méthode, j’ai eu quelques résultats hasardeux (cette commande est implémentée par certains serveurs, mais pas par Tomcat). C’est pour cela que je préfère la Hard Way.

The Hard Way: implémentation de Cache-Control avec un Listener

Notre implémentation va, ni plus, ni moins ajouter un champ dans les headers HTTP émis par notre serveur. Pour cela, nous allons utiliser créer un Listener, puis le configurer via web.xml (fichier standard paramétrant toute application web.

Création du Listener

Nous allons créer un Listener afin d’ajouter automatiquement un header à chaque requete.

/**
 *
 */
package com.diilo.ncs.skeleton.web;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;

/**
 * This filter adds an expire date for caching in HTTP header.
 *
 * @author Eric Vialle / 5.freshminutes.it
 */
public class HeaderFilter implements Filter {

 /** Logger Log4J. */
 private final static Logger    LOG                    = Logger.getLogger(HeaderFilter.class);

 /** Name of the parameter, defining the duration in minutes, in web.xml */
 private final static String    HEADER_CONFIG_LABEL    = "durationSecondes";

 /** Field's name of the HTTP header. */
 private final static String    HEADER_GET_KEY        = "Cache-Control";

 /** template for the valueHeader of this HTTP header field. */
 private final static String    HEADER_INSTRUCTIONS    = "max-age=";

 /** value for the field defined in HEADER_GET_KEY and that will be added to any HTTP header. */
 private String                valueHeader;

 /**
 * Initialization of the Filter.
 */
 public void init(FilterConfig filterConfig) throws ServletException {

 String headerParam = filterConfig.getInitParameter(HEADER_CONFIG_LABEL);
 if (headerParam == null) {
 LOG.warn("No headers were found in the web.xml (init-param) for the HeaderFilter !");
 } else {

 this.valueHeader = HEADER_INSTRUCTIONS + headerParam;

 LOG.info("The following headers were registered in the HeaderFilter - " + HEADER_GET_KEY + " : "
 + this.valueHeader);
 }
 }

 /**
 * Called at each request.
 */
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
 ServletException {

 if (valueHeader != null) {
 // We add our field to the HTTP header
 ((HttpServletResponse) response).setHeader(HEADER_GET_KEY, this.valueHeader);
 }
 chain.doFilter(request, response);
 }

 /**
 * Called when the Filter is destroyed.
 */
 public void destroy() {
 this.valueHeader = null;
 }

}

Installation du Listener

L’installation se fait par le paramétrage du fichier web.xml. Le fichier web.xml suivant indique la classe de notre Listener (dans notre cas: com.diilo.ncs.skeleton.web.HeaderFilter) qui sera appelé pour toutes les requêtes finissant par .jpg, .png, .gif, c’est à dire à toutes les images. Dans le champs durationSeconds, nous avons indiquée quel sera la durée de notre cache en secondes.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="diiloncswebserver" version="2.5"
 xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd">

...

<!-- Add cache to files -->
<filter>
<description>Set HTTP headers for a mapping.</description>
<filter-name>HeaderFilter</filter-name>
<filter-class>com.diilo.ncs.skeleton.web.HeaderFilter</filter-class>
<init-param>
<description>Add an Expires Header</description>
<param-name>durationSecondes</param-name>
<param-value>2592000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HeaderFilter</filter-name>
<url-pattern>*.jpg</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>HeaderFilter</filter-name>
<url-pattern>*.png</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>HeaderFilter</filter-name>
<url-pattern>*.gif</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>

....

</web-app>

Sources:

  • Caching in HTTP selon le W3
  • Configure Web App by Caucho


Catégories
Java, Java EE, Tutoriel
Tags
Cache-Control, http, optimisation, Tomcat
Flux rss des commentaires
Flux rss des commentaires
Trackback
Trackback

« Compiler son code? “It’s so 2000s” ou un apercu de Play et JRebel Introduction au NoSQL (et de Redis) ou le compte rendu du NoSQL User Group Paris de Février 2010 »

One Response to “Gérer le Cache-Control HTTP dans une application Web Java EE avec Tomcat”

  1. Optimiser le temps de chargement pour le web mobile avec iPhone, jQTouch, Struts 2 et Tomcat – 5.FreshMinutes.IT – Java & IT dit :
    Mercredi 24 février 2010 à 9:14

    [...] Les éléments sont mis en cache uniquement si le header HTTP du serveur web le “lui dit”, avec un champ comme Cache-Control vous trouverez plus d’explications, sur ce précédent billet [...]

Leave a Reply

Cliquez ici pour annuler la réponse.

Articles récents

  • Push & communications asynchrones sur iOS (iPhone/iPad)
  • Optimiser le temps de chargement pour le web mobile avec iPhone, jQTouch, Struts 2 et Tomcat
  • La philosophie du Domain Driven Design User Group et l’état des lieux * Users Group en Février 2010
  • Introduction au NoSQL (et de Redis) ou le compte rendu du NoSQL User Group Paris de Février 2010
  • Gérer le Cache-Control HTTP dans une application Web Java EE avec Tomcat
  • Compiler son code? “It’s so 2000s” ou un apercu de Play et JRebel
  • Le blog change d’adresse
  • Le Paris JUG a fêté ses 2 ans: compte-rendu

Navigation

  • Actualités Flux pour tous les articles classés dans Actualités
  • Architecture IT Flux pour tous les articles classés dans Architecture IT
  • Base de données Flux pour tous les articles classés dans Base de données
  • Java Flux pour tous les articles classés dans Java
    • Dévelopement Tips Flux pour tous les articles classés dans Dévelopement Tips
    • EDI Flux pour tous les articles classés dans EDI
    • J2ME Flux pour tous les articles classés dans J2ME
    • J2SE Flux pour tous les articles classés dans J2SE
    • Java EE Flux pour tous les articles classés dans Java EE
    • Tutoriel Flux pour tous les articles classés dans Tutoriel
  • Non classé Flux pour tous les articles classés dans Non classé
  • NoSQL Flux pour tous les articles classés dans NoSQL

Promo

Mots Clefs

adobe apache application web Base de données benchmark bugs c# checkstyle dérivation eclipse find bugs findbugs flex framework play google gzip http iPhone jar Java Java User Group java web start JVM microsoft mysql object objet open source optimisation oracle performance plugin pmd polymorphisme qualité recrutement rich internet application serveur silverlight struts struts 2 sun test Tomcat web

WP Cumulus Flash tag cloud by Roy Tanck and Luke Morton requires Flash Player 9 or better.

Twitter

  • J'ai testé OnLive Games sur mon Mac en Wifi: vraiment impressionnant que les possibilités du cloud gaming 2011-01-17
  • More updates...

Livres Pour Aller Plus Loin…

Blogoliste

  • Berthou.com
  • Le blog de hugu
  • PHP – Le Blog de Fatiha
  • techno.blog(java4it)
Get Adobe Flash playerPlugin by wpburn.com wordpress themes
rss Flux rss des commentaires valid xhtml 1.1 design by jide powered by Wordpress get firefox