Calling a Servlet in Java Code through a Post Request - or: how Service Oriented we Are html

Calling a Servlet in Java Code through a Post Request – or: how Service Oriented we Are

For one of our current Java development efforts – a Web application based on JSP, Struts, Oracle ADF technologies – we had to develop functionality to transforms HTML documents into PDF files. Wrapping a previously built set of classes in a well defined interface, we quickly had the job done. Then we started to integrate these classes into the project where the functionality was needed. We ran into several issues with versions of the libraries used. Then we stepped back, and started to rethink.

Why did we try to completely integrate the Html2Pdf converter in the Web Application itself? Why not think much more service oriented? Why not make this facility available in a more generic fashion? So we decided to create a Servlet frontend for our Html2Pdf converter component and package and deploy it as a web application in its own right. At this point, the web application we were building that needed this conversion functionality – with XSL-FO and Apache FOP inside – could simply call on the servlet, sending in the HTML document and receiving back an output stream that held the PDF document. And anyone else could also call upon this service. It can even run in an entirely different servlet container. The interface is as simple as a URL, accessed through a post-request with a single parameter.

Having made this decision made us feel a lot better. Decoupling, no hassle with the order of jars on the classpath, no recoding the Html2Pdf converter to work with the libraries used by the main web application. Having the service available to other applications as well. It is all too good to be true.

Well of course there is some overhead: the call to the servlet will be somewhat slower than a local call to an integrated class would have been. Then again, compared to the actual time it takes to create the XSL-FO and have FOP render the PDF, this additional overhead is negligible. Another drawback of the service oriented solution is of course the additional web application we have to manage. Once it is running, it should not require any administration, but it is an extra administrative burden.

Posting the HttpRequest to the Service URL from the Java application

Calling the service from Java is as simple as accessing a URL using the URLConnection object. Well, actually, even though I know it to be simple, I still had to look in one or two books and Google a little. It is not like I make URL calls, sending Post Requests all the time. But with all the resources I found – and I especially liked this one: http://www.marcellosendos.ch/booking/documentation/chapter2.html – it took me less than 20 minutes to get it to work, a call from Java to my Html2PDF service setup as a servlet:

package model.utils;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

public class Html2PDFServletTester  {
  public Html2PDFServletTester() {
  }
  // the hard-coded URL to the Service I want to invoke (should be injected of course)
  private static final String BASE_URL = "http://10.0.0.155:8988/HTML2PDFConverter-Client-context-root/servlet/Html2PdfServlet";

  public String parseISToString(InputStream is){
    DataInputStream din = new DataInputStream(is);
    StringBuffer sb = new StringBuffer();
    try {
      String line = null;
      while((line=din.readLine()) != null){
      sb.append(line+"\n");
      }
    } catch(Exception ex){
        ex.getMessage();
      }
      finally {
        try {
          is.close();
        } catch(Exception ex){}
    }
    return sb.toString();
  }

  public void convert()
  {
    // see http://www.marcellosendos.ch/booking/documentation/chapter2.html for example code
    try {
      HTML2PDFConverter converter = new HTML2PDFConverter();
      File inputFile = new File("theInputHtmlDocument.htm");
      FileInputStream in = new FileInputStream(inputFile);
      String inputHtml = parseISToString(in);


      URL url = new URL(BASE_URL);
      URLConnection con = url.openConnection();
       // inform the connection that we will send output and accept input
      con.setDoInput(true);
      con.setDoOutput(true);

     // Don't use a cached version of URL connection.
     con.setUseCaches (false);
     con.setDefaultUseCaches (false);
     con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
     // define a new PrintWriter on the output stream
     PrintWriter outWriter = new PrintWriter(con.getOutputStream());

     // send data to the servlet
     outWriter.print("htmlText="+inputHtml);
     outWriter.close();

     InputStream input = con.getInputStream();
     File outputFile = new File("TheResultingConverted.pdf");
     FileOutputStream out = new FileOutputStream(outputFile);

     boolean eof = false;
     // read all bytes from the input and write them to the output
     while (!eof) {
       int byteValue = input.read();        // read  the stream
       out.write(byteValue);
       if (byteValue  == -1)
         eof = true;
     }
     out.close();
    } catch(FileNotFoundException fnfe)
    {
      fnfe.printStackTrace();
    } catch(IOException ioe)
    {
      ioe.printStackTrace();
    }
  }

public static void main(String[] args) {
    Html2PDFServletTester h = new Html2PDFServletTester();
    h.convert();
}

}

Thanks to my nameless friends who share their code and suggestions. Thanks to Rob B. for getting it right in the end. Next time, we can find it here in this post…

4 Comments

  1. harpreet October 10, 2008
  2. Swaminathan June 29, 2007
  3. Ahmet YILMAZ November 30, 2006
  4. Wijaya Kusumo March 30, 2006