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(); } } }

Recent Comments