Sto servendo immagini dal mio servlet. Il tipo di contenuto della risposta è image / jpeg. Trovo che le immagini richieste dal mio servlet non siano memorizzate nella cache. Come faccio a farli memorizzare nella cache come normalmente le richieste di file sono? Ho provato a impostare Cache-Control: pubblico ma inutilmente.
Il servlet predefinito che serve contenuto statico in contenitori come Tomcat non imposta alcuna intestazione di controllo della cache. Non è necessario scrivere un servlet solo per quello. Basta creare un filtro come questo,
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long expiry = new Date().getTime() + cacheAge*1000; HttpServletResponse httpResponse = (HttpServletResponse)response; httpResponse.setDateHeader("Expires", expiry); httpResponse.setHeader("Cache-Control", "max-age="+ cacheAge); chain.doFilter(request, response); }
Ogni volta che vuoi aggiungere il controllo della cache, aggiungi il filtro alle risorse in web.xml. Per esempio,
CacheControl filters.CacheControlFilter CacheControl /images/*
È necessario inviare le ETag
, Last-Modified
e Expires
lungo la risposta. L’ ETag
rappresenta l’identificatore univoco del file (solitamente composto in base a una combinazione di datafile, data e ora e timestamp lastmodified). L’ Last-Modified
rappresenta l’ultimo timestamp modificato del file. L’intestazione Expires
indica per quanto tempo il client è autorizzato a mantenere il file nella cache. Se la cache è scaduta e ETag
o Last-Modified
sono disponibili, il client invierà una richiesta HEAD
per verificare se è necessario rinnovare il file. In caso contrario, la Expires
verrà nuovamente posticipata di conseguenza.
Puoi trovare qui un esempio di servlet che gestisce tutto ciò (e riprende i resumes e GZIP automatico): FileServlet che supporta curriculum e GZIP
Ad esempio, se desideri memorizzarli nella cache per 1 mese:
Calendar inOneMonth = Calendar.getInstance(); inOneMonth.add(Calendar.MONTH, 1); response.setDateHeader("Expires", inOneMonth.getTimeInMillis());
(questo è in un Filter
che gestisce il modello *.jpg
, ad esempio)
Ma le immagini dovrebbero essere memorizzate nella cache per impostazione predefinita: controlla i filtri e le configurazioni per vedere se qualcosa non sta impostando i parametri della cache in modo errato.
Ok .. sembra che i campi di intestazione predefiniti dovrebbero abilitare la memorizzazione nella cache. Ho trovato una soluzione in un altro forum. Apparentemente, è necessario impostare in modo esplicito una lunghezza del contenuto nella risposta. Mi chiedo perché però. Pensavo che HttpServletResponse lo avrebbe fatto per noi. Ad ogni modo, ha funzionato come un incantesimo e l’immagine è stata memorizzata nella cache.