Joachim Sauer
Joachim Sauer

Reputation: 308269

Reading/Writing XML Files with Spring Integration

I'm currently implementing a few import/export mechanisms with Spring Integration and all in all it goes quite well, but there seems to be a gap in the capabilities that I don't understand:

There is Spring Integration File for polling directories, writing to files, ... I can use this to poll a directory and get a Message<File> for every file I'm interested in.

There is Spring Integration XML for handling Document objects, apply XPath, XSLT, ... I can use this to analyze XML documents, enrich headers using XPath, split documents, ...

What I'm missing is the link between the two:

Marshallers/Unmarshallers seem to be exactly what I'm looking for (or at least bring me halfway to a byte[]), but they seem to only be capable to transforming a Document to/from a POJO via some mapping framework.

For parsing I can help myself with this simple class:

public class FileToDocumentTransformer extends AbstractFilePayloadTransformer<Document> {
    @Override
    protected Document transformFile(File file) throws Exception {
        return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
    }
}

But I have not found a suitable counterpiece to this and I can't believe that Spring Integration doesn't already come with this trivial ability built-in.

What am I missing?

Upvotes: 0

Views: 2823

Answers (2)

Joachim Sauer
Joachim Sauer

Reputation: 308269

I've ended up writing this class:

public class DocumentToBytesTransformer {
    public byte[] transform(Document document) throws Exception {
        Transformer tr = TransformerFactory.newInstance().newTransformer();
        tr.setOutputProperty(OutputKeys.INDENT, "yes");
        tr.setOutputProperty(OutputKeys.METHOD, "xml");
        tr.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
        tr.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        tr.transform(new DOMSource(document), new StreamResult(baos));
        return baos.toByteArray();
    }
}

With this configuration:

<int:service-activator method="transform">
    <bean class="package.DocumentToBytesTransformer"/>
</int:service-activator>

For me this is in a <chain>, otherwise you'd need input-channel and output-channel, of course.

I'm pretty sure that this is not the best possible solution (which is why I asked this in the first place), but it works for me.

Upvotes: 0

Gary Russell
Gary Russell

Reputation: 174779

See DefaultXmlPayloadConverter.convertToDocument. This converter is used internally in many endpoints (XPath in particular, but others too). It can handle File and String payloads. You can invoke it directly as a transformer too.

See the transformer package in the spring-integration-xml project for more info.

Upvotes: 1

Related Questions