Formatted XML output in CXF?

First off, the way to get formatted output of XML is to set the right property on the marshaller (typically JAXB when working with CXF, which is OK since JAXB does a creditable job). That is, somewhere you're going to have something doing this:

marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

The issue is that you don't necessarily want to have all output formatted; it adds quite a bit to the overhead. Luckily, you're already producing an explicit Response, so we can just use more features of that:

Marshaller marshaller = JAXBContext.newInstance(entity.getClass()).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
StringWriter sw = new StringWriter();
marshaller.marshal(entity, sw);

return Response.ok(sw.toString(), MediaType.APPLICATION_XML_TYPE).build();

Another method is mentioned in this JIRA issue (itself closed, but that's not so much of an issue for you):

The workaround is to register a custom output handler which can check whatever custom query is used to request the optional indentation:

http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/FormatResponseHandler.java

JAXBElementProvider and JSONProvider are driven by the JAXB Marshaller so by default they check a Marshaller.JAXB_FORMATTED_OUTPUT property on the current message.

This leads to code like this:

public class FormattedJAXBInterceptor extends AbstractPhaseInterceptor<Message> {
    public FormattedJAXBInterceptor() {
        super(Phase.PRE_STREAM);
    }

    public void handleMessage(Message message) {
        message.put(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    }

    public void handleFault(Message message) {
        message.put(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
    }
}

The CXF site discusses registration of interceptors.

Tags:

Java

Xml

Jax Rs

Cxf