I had a problem with having to show images in one of our projects one time. I was supposed to get an image from some server’s filesystem, copy it to my web server and show it online. Problem is, I had to copy each image to my own web server before I can do so. It was a dilemma because as time goes by, there is a tendency for my web server’s hard disk storage to get full. Thankfully, Alain, one of my teammates, brought up the idea of making use of Java servlets.
A previous post talked about being able to let users download a certain file (say, a PDF or some TIFF image) “on the fly”, specifically in WebLogic Workshop, where you can’t explicitly link to some PDF or other file from an action method, only to JSP or HTML files. I made use of that approach at that time because I had not much choice on how to solve the problem. But with servlets, I realized that you can actually do it in a more elegant (read: cleaner) manner, especially that JSPs aren’t supposed to have Java code in them — well, ideally. That would simply be a violation of the MVC concept.
I never thought Java servlets would be this easy! In a nutshell, here are the requirements that I did:
- Setup your application’s web.xml to know which Java class (the “servlet”) points to which alias;
- Setup your Java class that subclasses javax.servlet.http.HttpServlet;
- Test!
The first step involves modifying your web.xml. This maps your Java servlet to some alias such that, whenever that alias is accessed, the servlet runs.
[sourcecode language=”xml”]
<servlet>
<servlet-name>PDFServlet</servlet-name>
<servlet-class>com.wordpress.tlw.servlet.PDFServlet</servlet-class>
</servlet>
<!–
Make sure that in web.xml, all <servlet> tags come before
<servlet-mapping> tags; it will just cause a warning if you
didn’t, but why do when you can avoid it?
–>
<servlet-mapping>
<servlet-name>PDFServlet</servlet-name>
<url-pattern>/Servlet/PDFServlet</url-pattern>
</servlet-mapping>
[/sourcecode]
Then, the code for a sample servlet is shown below.
There’s doGet() and doPost() methods, either of which you can customize to do whatever you please depending on how data is submitted when this servlet is invoked. For my case, it was just a simple implementation of showing to a user the said PDF.
[sourcecode language=”java”]
package com.wordpress.tlw.servlet;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet that will serve PDF files to the client. If s/he has a plugin for PDF
* (i.e., Adobe PDF), it will be shown within the browser; otherwise, s/he will
* be prompted to download it.
*
* Based from tips and tricks by Alain Ferdinand Laguipo c",)
*
* @author Ronx Ronquillo
*/
public class PDFServlet extends javax.servlet.http.HttpServlet
{
// The MIME type associated with the kind of media to be served.
// For more info see http://www.utoronto.ca/webdocs/HTMLdocs/Book/Book-3ed/appb/mimetype.html
final static String CONTENT_TYPE = "application/pdf";
/**
* Default (empty) constructor
*/
public PDFServlet(){ }
public void doGet(HttpServletRequest request, HttpServletResponse response){
processRequest(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response){
doGet(request, response);
}
/**
* processRequest gets the byte array form of the document and streams it to response.
*
*/
public void processRequest(HttpServletRequest request, HttpServletResponse response)
{
response.setContentType(this.CONTENT_TYPE);
try{
File file1 = new File("D:/somePDF.pdf");
FileInputStream fs = new FileInputStream(file1);
byte[] byteArray = new byte[(int) file1.length()];
fs.read(byteArray);
fs.close();
// Write the PDF stream to the response; this way, the web browser will then handle it depending
// on its settings (i.e., display in-browser if with plugin, or prompt for download, etc.)
response.getOutputStream().write(byteArray);
}catch(Exception e){
this.outErrorMessage(response, "Some exception occurred: " + e.getMessage());
return;
}
}
/**
* outErrorMessage() displays in plain text, if, for whatever reason, an exception occurs
* during the display of the PDF. You can choose to display an HTML (content type: text/html)
* here if you prefer.
*/
private void outErrorMessage(HttpServletResponse response, String errorMsg)
{
response.setContentType("text/plain");
try{
PrintWriter out = response.getWriter();
out.println(errorMsg);
}catch(Exception e){ }
}
}
[/sourcecode]
If all goes well, accessing the servlet to test it should go smoothly like this:
As you’ve seen in the screenshot above, the alias defined in web.xml matters because that is the path that the servlet takes when it’s tested in the browser. Make sure that it is unique so problems will not arise.
I think I better do some additional reading with servlets. More can be done with these, actually. 🙂
special mention. lol.
regarding the web.xml config, i believe this is used to match the url with the httpservlet class to be executed. you might get a 404 if you don’t set this.
Of course! I’m quite thankful you suggested this! 😀
Yeah, good point! Thanks for the additional explanation. Forgot that detail, hehehe!