Women in Technology

Hear us Roar



Article:
  Two Servlet Filters Every Web Application Should Have
Subject:   MIME types and Servlets that generate binary data
Date:   2003-12-11 22:50:25
From:   jfalkner
Response to: MIME types and Servlets that generate binary data

The filter should work fine for binary content. To set the MIME type of a response the filter relies on the ServletContext.getMimeType() method. Make sure the MIME type for your particular URL is appropriately set in either web.xml for your web app, or for your container.


For example. If I want to cache JPEG images, I could map the filter as follows.


<filter-mapping>
<filter-name>CacheFilter</filter-name>
<url-pattern>*.jpg</url-pattern>
</filter-mapping>


And make sure the MIME type "image/jpeg" was set for the "jpg" extension.


<mime-mapping>
<extension>jpg</extension>
<mime-type>image/jpeg</mime-type>
</mime-mapping>


You would apply the same method for other MIME types and extensions.

Full Threads Oldest First

Showing messages 1 through 7 of 7.

  • MIME types and Servlets that generate binary data
    2003-12-12 13:29:00  anonymous2 [View]

    Right. I know that much, but the problem is when you don't actually generate a binary file dynamically, but have the servlet essentially do the following (in pseudocode):

    doGet(...){
    Image img = createImageDynamically();
    response.setContentType("image/jpeg");
    response.getOutputStream().write(img);
    }

    Here, assume that servlet is named MyImageServlet. Even assume that the servlet mapping is MyImage.jpg. AFAIK, the <mime-mapping> tag won't work (since it's only for static files). What one can do is something like the following:

    1) in CacheResponseWrapper, declare:
    String contentType;
    2) in CacheResponseWrapper, override setContentType as follows:
    public void setContentType(String type){
    origResponse.setContentType(type);
    contentType = type;
    }
    3) provide an accessor for the contentType String
    4) in CacheFilter, make sure to cache the results of getContentType along with the byte output stream.

    I'm not sure if this is teh best way, but it works and seems not to be *too* crazy. Obviously open to better solutions.

    On another note, I was wondering how we could cache pages that use cookies or sessions. Any ideas anyone?
    • MIME types and Servlets that generate binary data
      2003-12-12 15:07:35  jfalkner [View]

      I was wondering how we could cache pages that use cookies or sessions. Any ideas anyone?

      Could you clarify? What about the cookies or session would you want to use for either identifying cached information or for storing in the cache?

      You can always cache more than just the content returned by a response. You could have a filter save multiple files in your cache, say one for content, one for session information, etc. However, you will have to have a creative method for figuring out what cache information to use. Perhaps something along the lines of loading user-specific cache information when they log in, or by detecting a cookie you've saved on their machine.
      • MIME types and Servlets that generate binary data
        2003-12-15 09:02:11  anonymous2 [View]

        For example, say that part of a web app displays a calendar whose events are particular to the user and whose month is particular to some session variable. If one wanted to use a caching filter to reduce the time of calendar generation, it seems that the filter would have to dig through session variables to determine what user is logged in and what month they have chosen. This is not difficult, but when one has a customized situation like this, it seems that the CacheFilter will have to be customized as well. I'm interested in knowing if there is a way to do this in a more generic way - namely, so that a caching filter can be used in such a situation without having to tailor it so that it works *only* in this situation.
        • MIME types and Servlets that generate binary data
          2004-01-07 18:52:12  jfalkner [View]

          Sure, you could solve this problem a few ways. One way is to cache based on URL parameters (which I think this filter does...) and simply put the information you care about in the URL.

          Another way would be to add another level of abstraction to the cache filter, e.g. allow cache-control objects to be registered to the filter, then have the filter both check the URL/headers/etc and the registered cache-control objects. It would then be up to you to code cache-control objects (say one for your calendar) and register them with the filter.
    • MIME types and Servlets that generate binary data
      2003-12-12 13:40:31  anonymous2 [View]

      Also, even if <mime-mapping> worked, it could be a problem if the content type returned by the servlet can differ. EG, imagine an image servlet which takes a GET parameter 'imageType'. Let's say, for discussion's sake, that imageType can be JPEG, GIF, SVG, PNG, etc. In this case, the URL will be distinct for different contentTypes, but <mime-mapping> cannot be used. The above-posted solution works though. I still wonder why Sun didn't include a getContentType method in their default response object.
      • MIME types and Servlets that generate binary data
        2003-12-12 14:58:19  jfalkner [View]

        True, but a good point is that you can map your servlet to both "MyServlet.jpg" and "MyServlet.png", then use the correct URL based on if you want a JPG or a PNG -- same for other extensions and MIME types. I'd argue this is the way you should do dynamic images/content unless you really must do it a different way.
        • MIME types and Servlets that generate binary data
          2004-01-26 21:45:24  jleech [View]

          But isn't it a goal to make the filters as easy as possible to retrofit to existing applications? Sure, you could go in, add the filters, change lots of links to accomodate them, and add lines of code to web.xml to map everything -- Or just cache the response headers along with the rest of the response and everything is much simpler.
          Here's a real-world example of a situation where your suggestion wouldn't work -- and you really must do it a different way: A web form that lets the user input a bunch of parameters, including ouput format, e.g. { .pdf, .xml, .csv, .html }.
          The only compelling reason I can see to use extensions on the URLs for the content is to satisfy really old, broken versions of Internet Explorer. And you can trick them anyway by appending ?.pdf or &.pdf to the URL...