Httpcache on springboot

1.4k views Asked by At

I have springboot application that requests an image from url then display it on browser. I want to cache my response using cache-control header.

I use ResponseEntity and already set my header with eTag. I already checked response header in my browser and it shows :

Cache-Control:"max-age=31536000, public"
Content-Type:"image/jpeg;charset=UTF-8"
Etag:"db577053a18fa88f62293fbf1bd4b1ee"

my request also have If-None-Match header. But, I always get 200 status instead of 304.

Here's my code

@RequestMapping(value = "/getimage", method=RequestMethod.GET)
public ResponseEntity<byte[]> getImage() throws Exception {
    String url = "www.example.com/image.jpeg";
    String eTag = getEtag(url);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(new MediaType("image", "jpeg"));
    headers.add("Cache-Control", "max-age=31536000, public");
    headers.add("ETag", eTag);

    URL imageUrl = new URL(url);
    InputStream is = imageUrl.openStream();
    BufferedImage imBuff = ImageIO.read(is);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(imBuff, "jpeg", baos);
    byte[] image = baos.toByteArray();

    return new ResponseEntity<byte[]>(image, headers, HttpStatus.OK);
}

Can anyone help me?

UPDATE

I tried using method described in Unable to cache images served by Spring MVC so my code become :

@RequestMapping(value = "/getimage", method=RequestMethod.GET)
public ResponseEntity<byte[]> getImage() throws Exception {
    String url = "www.example.com/image.jpeg";
    String eTag = getEtag(url);

    URL imageUrl = new URL(url);
    HttpURLConnection httpCon = (HttpURLConnection)imageUrl.openConnection();
    long lastModified = httpCon.getLastModified();

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(new MediaType("image", "jpeg"));
    headers.add("Cache-Control", "max-age=31536000, public");
    headers.add("ETag", eTag);
    headers.add("Last-Modified", new Date(lastModified).toString());

    if (webRequest.checkNotModified(eTag)) {
        return null;
    }
    InputStream is = imageUrl.openStream();
    BufferedImage imBuff = ImageIO.read(is);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(imBuff, "jpeg", baos);
    byte[] image = baos.toByteArray();

    return new ResponseEntity<byte[]>(image, headers, HttpStatus.OK);
}

But now i always get 304 status code even if i change the url. I checked webRequest.checkIsNotModified(...) either by eTag and last-modified and it always return true. Did I do something wrong here?

1

There are 1 answers

0
afik On BEST ANSWER

I ended up changing my code. Instead of using webRequest.checkNotModified(eTag) i manually check last-modified and eTag from my resource (which is from s3) and compare it to if-modified-since and if-none-match in request header.

Besides, i also move everything related to http caching in a filter.