Stream and Serve with Java Servlets

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:

 

  1. Setup your application’s web.xml to know which Java class (the “servlet”) points to which alias;
  2. Setup your Java class that subclasses javax.servlet.http.HttpServlet;
  3. 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.

 


<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>

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.


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){ }
 }
}

If all goes well, accessing the servlet to test it should go smoothly like this:

 

Asia United Bank Statement of Account PDF sample
Access it in any web browser to test. It will display inside the browser if you have say, Adobe’s PDF plugin installed. Otherwise it will prompt to download the file.

 

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.🙂

2 thoughts on “Stream and Serve with Java Servlets

  1. 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!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s