views:

51

answers:

4

Hi,

I have a servlet which serves an image file which was stored in a blob. If the requested image can't be found, I'd like to server a static image I have included in my war directory. How do we do this? This is how I'm serving the blob images from the datastore:

public class ServletImg extends HttpServlet {
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
  {
    MyImgWrapper obj = PMF.get().getPersistenceManager().
      getObjectById(MyImgWrapper.class, 'xyz');
    if (obj != null) {
      resp.getOutputStream().write(obj.getBlob().getBytes());
      resp.getOutputStream().flush();
    }
    else {
      // Here I'd like to serve an image from my war file. 
      /war/img/missingphoto.jpg
    } 
  }
}

yeah I'm just not sure how to get the image bytes from the image in my war dir, or if there's some other way to do it?

Thanks

+1  A: 

Follow Haveacafe's tutorial.

2nd result for Google: java war file resource.

mcandre
Ah yeah that looks like what Stroboskop is also recommending, just not sure what the path should be for the resource?
+1  A: 

I suggest you use the class loader to retrieve the file.

ClassLoader classLoader = this.getClass().getClassLoader();
InputStream in = classLoader.getResourceAsStream(fileNameInClasspath);
...
Stroboskop
How do I know what 'fileNameInClasspath' should be though? The image path is: [war/img/test.jpg]
A: 

Better way at this case will be simply return http redirect (status 301) to URL of this image.

splix
+1  A: 

The other answers recommending ClassLoader#getResourceAsStream() are expecting that the image is located in the classpath. You can however also obtain the image from the webcontent using ServletContext#getResourceAsStream(). The ServletContext is available in servlets by the inherited getServletContext() method.

InputStream input = getServletContext().getResourceAsStream("/img/missingphoto.jpg");

That said, reading and writing fully into/from a byte[] is not really memory efficient. Consider streaming through a small byte buffer (1~10KB) like so:

input = getServletContext().getResourceAsStream(path);
output = response.getOutputStream();
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
    output.write(buffer, 0, length);
}
BalusC
Ok this works perfectly - I just wonder if splix's solution would give better performance (http redirect)? I guess the browser would have to make another request, so overall it would be slower? Thanks
The performance difference is negligible. At least, a redirect makes it impossible to set the response status to 404 (invoke `response.setStatus(HttpServletResponse.SC_NOT_FOUND);` before writing to the outputstream). The response status makes more sense to searchbots and so on.
BalusC