No se pueden almacenar en caché las imágenes servidas por Spring MVC

Estoy tratando de servir algunos activos utilizando un controlador Spring MVC. Mis activos son administrados por bases de datos y, por lo tanto, deben ser servidos de esta manera. El servicio busca los metadatos del activo en la base de datos, lee el archivo del sistema de archivos y genera la respuesta.

Así es como se ve mi controlador.

@Controller
@RequestMapping("/assets")
public class AssetController {

    @Autowired
    private AssetService assetService;

    @RequestMapping("/{assetName:.+}")
    public ResponseEntity<byte[]> getAsset(@PathVariable("assetName") String assetName) throws FileNotFoundException, IOException {
        Asset asset = assetService.findByName(assetName);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf(asset.getContentType()));
        headers.setCacheControl("max-age=1209600");
        headers.setLastModified(asset.getModifiedOn().getTime()); // always in the past

        return new ResponseEntity<byte[]>(assetService.toBytes(asset), headers, OK);
    }
}

Parece lo suficientemente simple y directo? Uno esperaría ver el navegador guardando en caché las imágenes. Pero a pesar de intentar todas las combinaciones deCache-Control, Expires, Last-Modified-On yETag, No he tenido exito

A continuación se muestran los encabezados HTTP (se eliminaron los encabezados irrelevantes) durante dos solicitudes sucesivas.

GET /adarshr-web/assets/Acer.png HTTP/1.1
Host: localhost:8080
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Cache-Control: max-age=1209600
Last-Modified: Sun, 21 Jul 2013 11:56:32 GMT
Content-Type: image/png
Date: Tue, 23 Jul 2013 21:22:58 GMT
----------------------------------------------------------

GET /adarshr-web/assets/Acer.png HTTP/1.1
Host: localhost:8080
If-Modified-Since: Sun, 21 Jul 2013 11:56:32 GMT
Cache-Control: max-age=0

HTTP/1.1 200 OK <-- Why not 304 Not Modified?
Cache-Control: max-age=1209600
Last-Modified: Sun, 21 Jul 2013 11:56:32 GMT
Content-Type: image/png
Date: Tue, 23 Jul 2013 21:23:03 GMT

Sin embargo, cuando intento la misma secuencia (Ctrl + F5 para la primera solicitud y F5 para las siguientes) en URL como

http://www.google.co.uk/images/srpr/logo4w.png (Logotipo de Google)http://fbstatic-a.akamaihd.net/rsrc.php/v2/yI/r/0PsXdTWc41M.png (Imagen móvil de Facebook)

Veo los encabezados como estos (que se muestran para la URL de Facebook) que indican que la respuesta está siendo almacenada en caché por el navegador.

GET /rsrc.php/v2/yI/r/0PsXdTWc41M.png HTTP/1.1
Host: fbstatic-a.akamaihd.net
Pragma: no-cache
Cache-Control: no-cache

HTTP/1.1 200 OK
Content-Type: image/png
Last-Modified: Sat, 15 Jun 2013 00:48:42 GMT
Cache-Control: public, max-age=31535893
Expires: Wed, 23 Jul 2014 21:27:47 GMT
Date: Tue, 23 Jul 2013 21:29:34 GMT
----------------------------------------------------------

GET /rsrc.php/v2/yI/r/0PsXdTWc41M.png HTTP/1.1
Host: fbstatic-a.akamaihd.net
If-Modified-Since: Sat, 15 Jun 2013 00:48:42 GMT
Cache-Control: max-age=0

HTTP/1.1 304 Not Modified <-- Note this
Content-Type: image/png
Last-Modified: Sat, 15 Jun 2013 00:48:42 GMT
Cache-Control: public, max-age=31535892
Expires: Wed, 23 Jul 2014 21:27:47 GMT
Date: Tue, 23 Jul 2013 21:29:35 GMT

Notas:

No tengo un<mvc:resources /> sección en mi configuración de primavera ya que estoy haciendo exactamente lo mismo en mi controlador. Incluso agregarlo no hace ninguna diferencia.No tengo unorg.springframework.web.servlet.mvc.WebContentInterceptor definido en la configuración de primavera de nuevo por las razones anteriores. He intentado agregar uno sin ganancia.He intentado todos los métodos explicados enhttps://developers.google.com/speed/docs/best-practices/caching.Puedo replicar esto en todos los navegadores.

Respuestas a la pregunta(1)

Su respuesta a la pregunta