Tuesday, December 9, 2014

Make XML-within-HTML display well in .jsp/Java content.

Inspired by this, I started a .jsp page like so:

<%@page import="org.owasp.encoder.Encode"%>
<%@page import="java.io.StringReader"%>
<%@page import="java.io.StringWriter"%>
<%@page import="javax.xml.transform.OutputKeys"%>
<%@page import="javax.xml.transform.Source"%>
<%@page import="javax.xml.transform.Transformer"%>
<%@page import="javax.xml.transform.TransformerFactory"%>
<%@page import="javax.xml.transform.stream.StreamResult"%>
<%@page import="javax.xml.transform.stream.StreamSource"%>

 
 

I then quickly break into Java at the top of the .jsp page before getting into significant HTML content. Amongst the stuff in Java is this blob of code which takes in an existing string called xml, reshapes it, and assigns it to a request attribute called xml also. The majority of this is shamelessly stolen from this.

Source xmlInput = new StreamSource(new StringReader(xml));
StringWriter stringWriter = new StringWriter();
StreamResult xmlOutput = new StreamResult(stringWriter);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", 5);
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(xmlInput, xmlOutput);
xml = xmlOutput.getWriter().toString();
request.setAttribute("xml", Encode.forHtml(xml));

 
 

I render the request attribute like so and I want to stress that the pre tag is required and without it all the work done so far becomes moot.

<pre>${xml}</pre>

 
 

It turns out that this line...

transformer.transform(xmlInput, xmlOutput);

...has to be wrapped in a try/catch if you implement it in a plain Jane Java class instead of a .jsp page. They may be made like this:

 
 

try
{
   transformer.transform(xmlInput, xmlOutput);
}
catch(Throwable t)
{
   String whatever = t.toString();
}

No comments:

Post a Comment