I have a simple image servlet to serve up images that I am storing in Mongodb GridFS. My servlet does not seem to be invoked, however.
Below you can see part of my web.xml, as well as the xhtml and html source in the browser. The jsf code seems to be working fine, and is pulling in the correct id. From my logs it seems that the doGet method n the servlet is not being invoked when the page is displayed.
Any ideas on why not would be much appreciated.
Here is my web.xml fragment:
<servlet>
<servlet-name>imageServlet</servlet-name>
<servlet-class>com.iLearn.view.servlet.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>imageServlet</servlet-name>
<url-pattern>/image/*</url-pattern>
</servlet-mapping>
Here is a fragment from an xhtml file:
<h:panelGrid id="resourcePanel" columns="4">
<a4j:repeat value="#{resourceUpload.resources}" var="res"
rowKeyVar="rowKey">
<h:panelGrid columns="1" style="width:100px; height:150 px;">
<h:graphicImage
value="image?id=#{res.idAsString}"
style="width:100px; height:100px;"
/>
<h:outputText value="#{res.name}" />
<h:outputText value="#{res.mimeType}" />
<h:outputText value="#{res.bytes}" />
</h:panelGrid>
</a4j:repeat>
</h:panelGrid>
And this is the source I am getting from my browser:
<table style="width:100px; height:150 px;">
<tbody>
<tr>
<td><img src="image?id=50ad879f93839043ffc4f156" style="width:100px; height:100px;" /></td>
</tr>
<tr>
<td>headshot.JPG</td>
</tr>
<tr>
<td>image/jpeg</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
<table style="width:100px; height:150 px;">
<tbody>
<tr>
<td><img src="image?id=50add3b09383f7b98d0f6e66" style="width:100px; height:100px;" /></td>
</tr>
<tr>
<td>workon.JPG</td>
</tr>
<tr>
<td>image/jpeg</td>
</tr>
<tr>
<td></td>
</tr>
</tbody>
</table>
Here is the doGet method in my servlet. Since it doesn’t hit the first log statement, I am pretty sure it never enters this method. Why not??
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String idString = request.getParameter("id");
getLogger().debug("ImageServlet got request to serve up image id = " + idString);
if((idString == null) || (idString.isEmpty())) {
getLogger().debug("Image id was null, so image not displayed");
return;
}
ObjectId id = new ObjectId(idString);
Resource image = getResourceRecordDao().load(id);
if(image == null) {
getLogger().warn("Could not find image with id: " + id);
return;
}
response.reset();
response.setContentType(image.getMimeType());
response.setHeader("Content-Length", String.valueOf(image.getSize()));
response.setHeader("Content-Disposition", "inline; filename=\"" + image.getName() + "\"");
image.render(response.getOutputStream());
}
A relative path in
<h:graphicImage>is relative to the current request URL. So if the currently requested page is by itself inside a folder like so http://examlpe.com/context/folder/page.xhtml, then the image will be downloaded from http://example.com/context/folder/image?id=123, while you would like to refer it from the context root as in http://example.com/context/image?id=123.Prefix the URL with
/to make it an absolute path and the<h:graphicImage>will render the URL relative to the context root.Unrelated to the concrete problem, you should return a 404 when the image is not found, not an empty response. It’s otherwise confusing for the client.
(do it in the other place as well where you’re checking the param itself)