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

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

问题描述

我面临的问题是如何将一大堆对象编组到一个 XML 文件中,如此之大,我无法一步编组完整的列表.我有一个方法以块的形式返回这些对象,但是然后我使用 JAXB 对这些对象进行编组,编组器返回一个例外,即这些对象不是根元素.对于您希望一步整理完整文档的正常情况,这是可以的,但如果我将 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 并且您的对象包装在 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天全站免登陆