如何使用JAXB Marshaller流式传输大型文件? [英] How to stream large Files using JAXB Marshaller?

查看:118
本文介绍了如何使用JAXB Marshaller流式传输大型文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临的问题是如何将大量对象编组到一个XML文件中,如此之大,我无法一步完成整个列表的编组。我有一个以块的形式返回这些对象的方法,但是然后我使用JAXB对它们进行编组,marshaller返回一个例外,即这些对象不是根元素。对于您希望在一个步骤中编组完整文档的正常情况,这是正常的,但如果我将JAXB_FRAGMENT属性设置为true,也会发生这种情况。

The Problem I'm facing is how to marshall a large list of objects into a single XML File, so large I can not marshall the complete list in one step. I have a method that returns these objects in chunks, but then I marshall these using JAXB, the marshaller returns with an exception that these objects are no root elements. This is ok for the normal case there you want to marshall the complete document in one step, but it also happens if I set the JAXB_FRAGMENT Property to true.

这是所需的XML输出:

This is the desired XML output:

<rootElem>  
    <startDescription></startDescription>  
    <repeatingElem></repeatingElem>
    <repeatingElem></repeatingElem>...
</rootElem>

所以我假设我需要某种类型的侦听器来动态加载下一大块的重复元素以将其提供给在他编写rootElement的结束标记之前的编组器。但是怎么做呢?到目前为止,我只使用JAXB来编组小文件,而JAXB文档没有给出该用例的大量提示。

So I assume I need some kind of listener that dynamically loads the next chunk of repeatingElements to feed it to the marshaller before he would write the closing tag of the rootElement. But how to do that? Up until now I only used JAXB to marshall small files and the JAXB documentation does not give much hints for that use case.

推荐答案

我知道这是一个老问题,但我在搜索另一个类似问题的重复时遇到了它。

I'm aware that this is an old question but I came across it while searching for duplicates of another similar question.

正如@skaffman建议的那样,你想要使用 JAXB_FRAGMENT 启用Marshal并将你的对象包装在JAXBElement中。然后,您反复编组重复元素的每个单独实例。基本上听起来你想要的东西大致是这样的:

As @skaffman suggests, you want to Marshal with JAXB_FRAGMENT enabled and your objects wrapped in JAXBElement. You then repeatedly marshal each individual instance of the repeated element. Basically it sounds like you want something roughly like this:

public class StreamingMarshal<T>
{
    private XMLStreamWriter xmlOut;
    private Marshaller marshaller;
    private final Class<T> type;

    public StreamingMarshal(Class<T> type) throws JAXBException
    {
        this.type = type;
        JAXBContext context = JAXBContext.newInstance(type);
        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    }

    public void open(String filename) throws XMLStreamException, IOException
    {
        xmlOut = XMLOutputFactory.newFactory().createXMLStreamWriter(new FileOutputStream(filename));
        xmlOut.writeStartDocument();
        xmlOut.writeStartElement("rootElement");
    }

    public void write(T t) throws JAXBException
    {
        JAXBElement<T> element = new JAXBElement<T>(QName.valueOf(type.getSimpleName()), type, t);
        marshaller.marshal(element, xmlOut);
    }

    public void close() throws XMLStreamException
    {
        xmlOut.writeEndDocument();
        xmlOut.close();
    }
}

这篇关于如何使用JAXB Marshaller流式传输大型文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆