Archive

Posts Tagged ‘Servlets’

XSL Transformation with JAXB

November 17th, 2009

The goal here is to take the output of a JAXB Marshaller and pass it straight to an xslt processor like JAXP. The issue with this is that JAXP takes it’s input from various sorts of input streams and JAXB marshaller outputs usually in some sort of output stream. I saw some (bad) solutions about changing an output stream into an input stream and then pass it to JAXP. eww. The cool thing about JAXB is that it can marshall into a SAX ContentHandler. And there is an implementation of ContentHandler that handles XSL transformations for us! Here is an example of a http servlet that will do an xslt transformation on a JAXB marshalled POJO and dump the results right into into the servlet’s output stream:

package org.codeangel.awesome;
 
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.*;
 
public class DisplayServlet extends HttpServlet {
 
  private Templates displayTemplate;
  private TransformerFactory transFact;
 
  @Override
  public void init() throws ServletException {
    //We are going to compile the xslt stylesheet on init and cache the result. 
    //(in this example display.xsl is in the root of the webapp)
    transFact = TransformerFactory.newInstance();
    try {
      displayTemplate = transFact.newTemplates(
        new StreamSource(getServletContext()
              .getResource("/display.xsl").toExternalForm())
      );
    } catch (TransformerConfigurationException e) {
      e.printStackTrace();
    } catch (MalformedURLException e) {
      e.printStackTrace();
    }
 
  }
 
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    //In this example I'm fetching an object from the servlet context, I could
    //just as easily got the object from hibernate, or any other datasource
    MyClass myObject = (MyClass)getServletContext().getAttribute("MyObject");
 
    //I just happen to be tranforming to html, you can change this as needed
    resp.setContentType("text/html");
 
    try {
      //set up JAXB
      JAXBContext jaxbc = JAXBContext.newInstance(MyClass.class);
      Marshaller marshaller = jaxbc.createMarshaller();
      OutputStream out = resp.getOutputStream();
 
      TransformerFactory transFact = TransformerFactory.newInstance();
      Result outputResult = new StreamResult(out);
 
      TransformerHandler handler = 
      ((SAXTransformerFactory) transFact).newTransformerHandler(displayTemplate);
      handler.setResult(outputResult);
 
      //this is where everything happens!
      marshaller.marshal(myObject, handler);
 
    }  catch (TransformerConfigurationException e) {
       e.printStackTrace();
    } catch (JAXBException e) {
      e.printStackTrace();
    }
  }
}

Java , , , , ,