2010-07-30 12 views
10

¿Alguien sabe cómo codificar un filtro de servlet que establecerá encabezados de caché en una respuesta para un tipo de archivo/contenido dado? Tengo una aplicación que sirve muchas imágenes, y me gustaría reducir el ancho de banda para alojarla teniendo el caché del navegador en las que no cambian muy a menudo. Idealmente, me gustaría poder especificar un tipo de contenido y hacer que establezca los encabezados apropiados cada vez que coincida el tipo de contenido.¿Filtro de servlet para el almacenamiento en caché del navegador?

¿Alguien sabe cómo hacerlo? O, mejor aún, ¿tienen un código de muestra que estarían dispuestos a compartir? ¡Gracias!

Respuesta

15

En su filtro tienen esta línea:

chain.doFilter(httpRequest, new AddExpiresHeaderResponse(httpResponse)); 

Cuando el envoltorio respuesta se parece a:

class AddExpiresHeaderResponse extends HttpServletResponseWrapper { 

    public static final String[] CACHEABLE_CONTENT_TYPES = new String[] { 
     "text/css", "text/javascript", "image/png", "image/jpeg", 
     "image/gif", "image/jpg" }; 

    static { 
     Arrays.sort(CACHEABLE_CONTENT_TYPES); 
    } 

    public AddExpiresHeaderResponse(HttpServletResponse response) { 
     super(response); 
    } 

    @Override 
    public void setContentType(String contentType) { 
     if (contentType != null && Arrays.binarySearch(CACHEABLE_CONTENT_TYPES, contentType) > -1) { 
      Calendar inTwoMonths = GeneralUtils.createCalendar(); 
      inTwoMonths.add(Calendar.MONTH, 2); 

      super.setDateHeader("Expires", inTwoMonths.getTimeInMillis()); 
     } else { 
      super.setHeader("Expires", "-1"); 
      super.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); 
     } 
     super.setContentType(contentType); 
    } 
} 

En resumen, esto crea un envoltorio de respuesta, que, sobre el ajuste del tipo de contenido, agrega el encabezado expira (Si lo desea, puede agregar cualquier otro encabezado que necesite). He estado usando este filtro + envoltorio y funciona.

See this question en un problema específico que esto resuelve, y la solución original de BalusC.

+3

Alternativamente, si usted tiene todos los archivos en una carpeta común, por ejemplo, '/ static', luego simplemente mapee el filtro en un' url-pattern' of '/ static/*' para que no necesite verificar el tipo de contenido cada vez y simplemente pueda establecer los encabezados de respuesta directamente. – BalusC

+0

Esto NO funcionará para los recursos SSL/TLS en GlassFish debido a que el contenedor agrega automáticamente los encabezados Pragma y Cache-Control. Si desea almacenar en caché estos recursos, debe eliminar/sobrescribir estos encabezados con algo como: super.setHeader ("Pragma", nulo); y super.setHeader ("Cache-Control", nulo). Cache-Control: "público" probablemente también funcione. Nota: Usar null puede no ser portátil ya que no está en la especificación. Puede haber una forma de desactivar el contenedor para que no agregue los encabezados, pero no está bien documentado. – Ryan

Cuestiones relacionadas