views:

54

answers:

4

Hi....

I've a jsp page which loads many images. I'd like to cache the images for faster loading.

I'll explain my idea, please correct it if it's wrong. I'm calling the picture loading servlet for each image and return as a BLOB. My idea is to add a modified date with the image and the other values like Last-Modified, expires, Cache-control and max age. And thereby make the browser understand if the image changes.

But how can i append a modified date to a BLOB? Or is there some better ideas to make them cachable?

Thanks...

A: 

Don't you want to amend the HTTP headers, rather than the actual image/BLOB itself ?

See this page for info on setting headers in the servlet response. I suspect you'll be looking at standard headers such as Expires.

Brian Agnew
A: 

I've a jsp page which loads many images. I'd like to cache the images for faster loading.

This is a Good ThingTM.

I'll explain my idea, please correct it if it's wrong. I'm calling the picture loading servlet for each image and return as a BLOB. My idea is to add a modified date with the image and the other values like Last-Modified, expires, Cache-control and max age. And thereby make the browser understand if the image changes.

For that you actually need the ETag, Last-Modified and optionally also Expires header. With the ETag header both the server and client can identify the unique file. You can if necessary use under each the database key for this. With the Last-Modified header header both the server and client knows if they both have the same version of the file. With the Expires header you can instruct the client when to re-request the file the firstnext time (thus, when the date as specified in Expires has been expired).

The Cache-Control header is not so relevant here as you just want to allow caching and the average client already does that by default.

For more information and a servlet example, you may find this article useful and maybe also this article for the case you'd be interested in tuning performance of a JSP/Servlet webapplication.

But how can i append a modified date to a BLOB? Or is there some better ideas to make them cachable?

Just add one more column to the database table in question which represents the insertion date. In most DB's you can just use now() function for this or even create it as an auto-trigger so that it get set automatically on every insert/update.

BalusC
+1  A: 

I believe you should set the appropriate headers for controlled caching.

You can always use the http protocol specs as a reference for sending and setting the appropriate headers (response headers).

You can have a look at the following links:

Caching in HTTP http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html

Http Protocol Header Field Definitions http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

regards,

andreas
A: 

(moved from the duplicate question)

Add a filter (javax.servlet.Filter) that adds the cache headers whenever the response contains an image. Something like:

public class StaticResourceCacheFilter implements Filter {

    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 void init(FilterConfig cfg) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;


        chain.doFilter(httpRequest, httpResponse);

        String contentType = httpResponse.getContentType();

        if (contentType != null && Arrays.binarySearch(CACHEABLE_CONTENT_TYPES, contentType) > -1) {

            Calendar inTwoMonths = Calendar.getInstance();
            inTwoMonths.add(Calendar.MONTH, 2);

            httpResponse.setHeader("Expires", DateUtil.formatDate(inTwoMonths.getTime()));
        } else {
            httpResponse.setHeader("Expires", "-1");
        }

    }

(where DateUtil is org.apache.commons.httpclient.util.DateUtil)

The above filter, of course, assumes you have set the right Content-Type for your images. Otherwise I think they might not be displayed properly in the browser, with or without cache.

To answer your question:

Is there any way to keep the images in cache until the image get modified in server.

That's a different scenario. You can store your images in some cache implementation (ehcache for example), but this is a server cache, not client cache.

Bozho