XMLMill - convert xml to pdf with java. Generate PDF from xml/xsl.

XMLMill User Guide

Version: 3.00 Date: January 2nd, 2008
This tutorial is opened in a separate window in order to maximize the legibility of this tutorial.
To return to XMLMill, close this browser window

This page as PDFPrinter friendly pageThis guide (!) as PDF

XMLMill in Servlets

As servlets are a regular Java classes (extending the HttpServlet class), XMLMill can be used like described in the previous chapter.

Prerequisites

Before you can use XMLMill in your servlet container, following jar files need to be copied to the project's WEB-INF/lib directory:

  • xmlmill.jar -- A version of the xmlmill.jar file
  • commons-logging-1.*.jar) -- A version of the commons-logging.jar file
  • In case your servlet container does not already use a JAXP compliant xml/xsl parser/transformer, you need to add these jar files also to the servlet container's or project's WEB-INF/lib directory.

Overview

When calling a JAXPTransformer instance from within your servlet, you will probably generate a .pdf document on-the-fly and send the result through the javax.servlet.ServletOutputStream instance contained in the HttpServletResponse object.

This section will only describe the extra steps needed when using XMLMill in your servlet container. Please refer to the previous chapter to know how to use the JAXPTransformer and JAXPErrorHandler classes in regular Java classes.

The extra steps are:

  • Set the content type of the response object to "application/pdf"
  • Define the OutputStream the JAXPTransformer should write the result to.

Example

Most of the time a web-based application wants to generate a report based on data selected by the user (e.g. generate a report of all outstanding invoices of a supplier that is currently shown in the user's browser).

images/servlet3.jpg
Select to enlarge

The steps to achieve this are:

  1. On the client's browser there is a form containing a button like 'generate report'.
  2. A servlet is invoked that (1) Generates an xml stream containing the data (2) Transforms the xml stream with a server-site xsl file using an instance of the JAXPTransformer() class.
  3. The generated PDF file is sent back to the browser.
  • All images and other external files needed should be stored on the server

In the example below a .xml and .xsl file is used to mimic two java.io.streams.

[001] 
[002] package testservlets;
[003] 
[004] import javax.servlet.*;
[005] import javax.servlet.http.*;
[006] import java.io.*;
[007] import java.util.*;
[008] import com.xmlmill.*;  
[009] import com.xmlmill.config.Configurator;
[010] 
[011] 
[012] public class Fetch extends HttpServlet
[013] {
[014] 
[015]   public void init(ServletConfig config) throws ServletException
[016]   {
[017]    // necessary to initialize servlet on IAS.
[018]    super.init(config);  
[019]    
[020]     // Following actions :
[021]     // 1. Define the logger instance    
[022]     // 1. Call configurator
[023]     // This should only be done in ONE servlet (if you have more
[024]     // servlets calling XMLMill's JAXPTransformer class).      
[025]     // All servlets using JAXPTransformer  instances will 
[026]     // use the same Logger; hence write the logmessages
[027]     // in the same logfile and will have the same loglevel.
[028]     
[029]     FileLogger logger = null;
[030]     
[031]     try {   
[032] 
[033]       ////////////////////////////////////////////////////
[034]       // DEFINE FIRST THE LOGGER INSTANCE TO USE        //
[035]       // HERE DEFAULT com.xmlmill.log.FileLogger        //
[036]       // (you can use any class which implements the    //
[037]       // org.apache.commons.logging.Log interface)      //
[038]       ////////////////////////////////////////////////////
[039] 
[040]       // Use the default FileLogger class
[041]       logger = new FileLogger("xmlmill");  
[042]       
[043]       // Get the realpath.
[044]       // This is necessary to set the logfile.   
[045]       this.realpath = this.getServletContext().getRealPath("/xmlxsl/");
[046]             
[047]       // Set logfime - Resin 2.1.0
[048]       //File logfile = new File(realpath+"log/xmlmill_"+(new 
            Date()).getTime()+".log");
[050] 
[051]       // Set logfile - Tomcat 4.0.4
[052]       File logfile = new File(realpath+"/log/xmlmill_"+(new 
            Date()).getTime()+".log");      
[054] 
[055]       // Set logfile  
[056]       logger.setFileName(logfile, false); 
[057]       
[058]       // Set the loglevel 
[059]       logger.setLevel("INFO");
[060] 
[061]       // Pass the logger to the XMLMill Configurator, so XMLMill can use 
            it.
[063]       Configurator.setLogger(logger);  
[064]     
[065]       //////////////////////////////////////////////
[066]       // INITIALIZE THE CONFIGURATOR              //
[067]       //////////////////////////////////////////////    
[068] 
[069]       // Set Configurator.
[070]       // Although this is optional it will force XMLMill to
[071]       // get a ClassLoader instance.  Some application servers
[072]       // have difficulty in finding a ClassLoader instance after
[073]       // the servlet is initialized.  Hence we do it here.
[074]       Configurator.configure();
[075]     
[076]     } catch (Exception e) {
[077]       throw new ServletException(e);
[078]     }        
[079]    
[080]  }
[081] 
[082]   public void doGet(HttpServletRequest request, HttpServletResponse 
        response)
[084]          throws ServletException, IOException
[085]   {
[086]      String realpath = this.getServletContext().getRealPath("/xmlxsl/");
[087] 
[088]      JAXPTransformer  transform; 
[089] 
[090]      try
[091]      {
[092]         // Tomcat 4.0.4 server
[093]         File xmlfile = new File(realpath + "/" 
              +request.getParameter("xml"));
[095]         File xslfile = new File(realpath + "/" 
              +request.getParameter("xsl"));
[097]         
[098]         // Mimic xml-stream and xsl-stream 
[099]         FileInputSteam xmlstream = new FileInputSteam(xmlfile);
[100]         FileInputSteam xslstream = new FileInputSteam(xslfile);        
[101] 
[102]         // Set ContentType 
[103]         response.setContentType("application/pdf");
[104]          
[105]         //Get the output stream 
[106]         javax.servlet.ServletOutputStream ostream = 
              response.getOutputStream();
[108] 
[109]         // Define an errorhandler(optional) 
[110]         JAXPErrorHandler ehandler = new JAXPErrorHandler(
[111]                                JAXPErrorHandler.ABORT_ON_ERROR );
[112] 
[113]         // Define a tranform object 
[114]         transform = new JAXPTransformer();
[115]  
[116]         // Set the xml file   
[117]         transform.setXMLStream(xmlstream); 
[118]   
[119]         // Set the xsl file 
[120]         transform.setXSLStream(xslstream); 
[121] 
[122]         // Define where xmlmill.dtd resides on the server 
[123]         transform.setBaseURL(xslfile);
[124] 
[125]         // Set the errorhandler      
[126]         transform.setErrorHandler(ehandler);    
[127] 
[128]         // Set transform outputstream 
[129]         transform.setOutputStream(ostream);
[130] 
[131]         // Log the xslfile-name (just as an example how to log)
[132]         Configurator.getLogger().debug("Start transformation...");
[133] 
[134]         // Check if the client is IE. 
[135]         String useragent = request.getHeader("User-Agent");
[136]         if ((useragent != null) && (useragent.indexOf("MSIE") != -1)) 
[137]           transform.setDocumentSize(8192);  
[138]           
[139]         // and transform. 
[140]         transform.transform();          
[141]  
[142]         // Set contentlength. 
[143]         response.setContentLength(transform.getDocumentSize());
[144] 
[145]         // Close stream 
[146]         ostream.flush();
[147]         ostream.close();       
[148] 
[149]         // Flush response buffer 
[150]         response.flushBuffer();
[151] 
[152]       } catch (Exception e){
[153]         PDXLogger.getPDXLogger().debug("Catch-error:" + e.getMessage());   
              
[155]     
[156]   }
[157]   
[158] }        
[159]         

1

Be sure to import the com.xmlmill package and the com.xmlmill.config.Configurator class.

2

Call the configurator, define the logging instance to use, set LogLevel.

3

The xml and xsl are represented as java.io.InputStream objects. In this example the data comes from java.io.File objects, but in real-life the java.io.InputStream objects could be generated by a sub-system.

4

The contenttype of HttpServletResponse object is defined as application/pdf.

5

We keep a reference to the javax.servlet.ServletOutputStream object (as it is needed later).

6

Define an errorhandler that will handle all warnings, errors, fatalErrors.

7

Define a transform object.

8

Define the xmlstream to be processed using the setXMLStream(java.io.InputStream) method.

9

Define the xslstream to be processed using the setXSLStream(java.io.InputStream) method.

10

Define the base directory (see Defining the Base URL for more information.

11

Set the errorhandler.

12

Define where the result should be sent to.

13

Check if the client is IE. If so, we set the minimumsize of the .pdf document to be at least 8192 bytes, so the client (IE) will certainly open it.

14

Do the transformation.

15

Define the outputstream's contentlength.

16

Flush and close the outputstream.

17

Flush the response buffer to be sure that all bytes are sent to the outputstream.

Copyright © 2001 - 2012. All rights reserved. XMLMill and XMLMill logo are trademarks of Pecunia Data Systems, bvba.
Powered by Apache CocoonPowered by XMLMill