Friday, January 20, 2012
Spring JAXB with CDATA Elements
I wanted to configure the Jaxb2Marshaller to support CDATA elements. This example works with Spring 3.1 and Java 6, using the Java 6 restricted XML parser classes to configure the CDATA elements.
<bean id="marshaller" class="org.springbyexample.marshaller.CdataJaxb2Marshaller">
<property name="cdataElements">
<list>
<value>^value</value>
</list>
</property>
...
import java.io.IOException;
import java.io.OutputStream;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang.ArrayUtils;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.XmlMappingException;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
import org.springframework.oxm.mime.MimeContainer;
public class CdataJaxb2Marshaller extends Jaxb2Marshaller {
private String[] cdataElements;
public String[] getCdataElements() {
return cdataElements;
}
public void setCdataElements(String[] cdataElements) {
this.cdataElements = cdataElements;
}
@Override
public void marshal(Object graph, Result result, MimeContainer mimeContainer) throws XmlMappingException {
if (ArrayUtils.isNotEmpty(cdataElements)) {
try {
Marshaller marshaller = createMarshaller();
com.sun.org.apache.xml.internal.serialize.XMLSerializer serializer =
createXMLSerializer(cdataElements, ((StreamResult)result).getOutputStream());
marshaller.marshal(graph, serializer.asContentHandler());
} catch (IOException e) {
throw new MarshallingFailureException(e.getMessage(), e);
} catch (JAXBException ex) {
throw convertJaxbException(ex);
}
} else {
super.marshal(graph, result);
}
}
@SuppressWarnings("restriction")
private com.sun.org.apache.xml.internal.serialize.XMLSerializer createXMLSerializer(String[] cDataElements, OutputStream cOut) {
// This code is from a sample online: http://jaxb.java.net/faq/JaxbCDATASample.java
// configure an OutputFormat to handle CDATA
com.sun.org.apache.xml.internal.serialize.OutputFormat of = new com.sun.org.apache.xml.internal.serialize.OutputFormat();
// specify which of your elements you want to be handled as CDATA.
// The use of the '^' between the namespaceURI and the localname
// seems to be an implementation detail of the xerces code.
// When processing xml that doesn't use namespaces, simply omit the
// namespace prefix as shown in the third CDataElement below.
of.setCDataElements(cDataElements); //
// set any other options you'd like
of.setPreserveSpace(true);
of.setIndenting(true);
of.setPreserveSpace(false);
// create the serializer
com.sun.org.apache.xml.internal.serialize.XMLSerializer serializer = new com.sun.org.apache.xml.internal.serialize.XMLSerializer(of);
serializer.setOutputByteStream(cOut);
return serializer;
}
}
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment