0

Problem in short:

  • GET on pictures/pic.png should first be treated by Jersey, then by tomcat itself
  • Reasons:
    1. tomcat knows when to send 304 Not Modified. (The response is client-specific)
    2. pic.png might need an update. The update should happen when a call to the picture is made.

Long explanation:

I have a picture on a given URL. The picture might need a referesh. I want to do the freshness-check at the time of the request. Therefore, I coded a jersey resource handling the request on the picture URL. It refreshes the picture on the filesystem if necessary. I do not want to re-code a caching mechansim, but rely on tomcat's implementation. Therefore, I would like to "forward" the request in the internal handler chain. I tried return new Viewable(sb.toString());, but a viewable is not a picture. What return type can I use?

I could let the concrete picture reside on another URL and send a 307 (Temporary Redirect). Always sending that as answer seems odd to me.

Possibly, the solution having the update at the "GET" method is wrong by design. Possibly, the "PUT"/"POST" method should update the picture and GET should always be handled by tomcat.

Why is the question titled "How can I emulate forward on 404 in jersey?". The feature com.sun.jersey.config.feature.FilterForwardOn404 does a similar thing: If the resource cannot be handled by jersey, it is forwarded through filter/servlet chain. I think, my problem is similar to that.

Related question: How to return a PNG image from Jersey REST service method to the browser

Community
  • 1
  • 1
koppor
  • 19,079
  • 15
  • 119
  • 161

1 Answers1

0

IMHO the best way to handle this is not to try to redirect the client but to go fetch the item requested yourself. You're trying to make jersey act in a way it's not supposed to behave. When someone calls a rest service for something like an image (not really the best use for a rest service anyway) you're supposed to respond with the image. So go fetch it from whatever cache it's in and return it. Don't ask the client to go get it.

You are welcome to delegate the fetching of that image to your cache service though...

Response getImage(...) {
   if(image.isNotCached()) {
       ... get image locally
      cacheService.set(image,key);
      return Response.ok().entity(<image>);
   } else {
      return Response.ok().entity(cacheServce.get(key);
   }
}

or something like that

Rick Mangi
  • 3,761
  • 1
  • 14
  • 17
  • The image is then always transferered over the wire, isn't it? I want to have a "304 Not Modiefied" as a reply if the image is not modified. Doing that dependend on the image state on the client makes me re-implementing http caching, doesn't it?. Why should I if tomcat already does it? – koppor Apr 02 '12 at 12:17
  • Then send the 304 with Response.ok().status(...) but I don't think tomcat does this caching... The client should be getting that from a downstream cache or cdn. – Rick Mangi Apr 02 '12 at 13:29
  • I don't want to send 304 or 307. Therefore I'm asking whether an emulation is possible. Tomcat can send 304. The 304, however, is client specific... – koppor Apr 12 '12 at 15:40
  • How do you think tomcat is aware that a resource being generated by a servlet has not been modified? I'm not sure where you think this is happening. AFAIK tomcat can't possibly know that this is the case. Are you talking about a file that lives as a static file on the filesystem that you need to refresh periodically? – Rick Mangi Apr 13 '12 at 03:23
  • Yes, I'm talking about a static file. Thus, tomcat can be aware whether it's modified. - Thus the queue Jersey, Tomcat-internal-handling. – koppor Apr 13 '12 at 07:16
  • Then you should modify that file offline with a scheduled task of some sort otherwise you will always be hitting the servlet. Alternatively you might want to look at urlrewrite filter (tuckey.org) which can intercept outbound responses and redirect to your servlet – Rick Mangi Apr 13 '12 at 13:58