【问题标题】:Jaxb marshaller implementation and handling IOExceptionJaxb marshaller 实现和处理 IOException
【发布时间】:2015-06-14 16:45:39
【问题描述】:

我们在使用 JAXB 生成 XML 文件时遇到了一些问题。(即使我们针对 XSD 进行验证,生成的文件也已损坏/混乱)。但是服务器日志中没有报错(catalina.out)

在我们进行调查时,我们碰巧在 com.sun.xml.internal.bind.v2.runtime.MarshallerImpl 中发现了以下代码段(这是 java 用于将 JAXB 对象编组为 XML 的运行时类)。

    /**
 * All the marshal method invocation eventually comes down to this call.
 */
private void write(Object obj, XmlOutput out, Runnable postInitAction) throws JAXBException {
    try {
        if( obj == null )
            throw new IllegalArgumentException(Messages.NOT_MARSHALLABLE.format());

        if( schema!=null ) {
            // send the output to the validator as well
            ValidatorHandler validator = schema.newValidatorHandler();
            validator.setErrorHandler(new FatalAdapter(serializer));
            // work around a bug in JAXP validator in Tiger
            XMLFilterImpl f = new XMLFilterImpl() {
                @Override
                public void startPrefixMapping(String prefix, String uri) throws SAXException {
                    super.startPrefixMapping(prefix.intern(), uri.intern());
                }
            };
            f.setContentHandler(validator);
            out = new ForkXmlOutput( new SAXOutput(f) {
                @Override
                public void startDocument(XMLSerializer serializer, boolean fragment, int[] nsUriIndex2prefixIndex, NamespaceContextImpl nsContext) throws SAXException, IOException, XMLStreamException {
                    super.startDocument(serializer, false, nsUriIndex2prefixIndex, nsContext);
                }
                @Override
                public void endDocument(boolean fragment) throws SAXException, IOException, XMLStreamException {
                    super.endDocument(false);
                }
            }, out );
        }

        try {
            prewrite(out,isFragment(),postInitAction);
            serializer.childAsRoot(obj);
            postwrite();
        } catch( SAXException e ) {
            throw new MarshalException(e);
        } catch (IOException e) {
            throw new MarshalException(e);
        } catch (XMLStreamException e) {
            throw new MarshalException(e);
        } finally {
            serializer.close();
        }
    } finally {
        cleanUp();
    }
}

private void cleanUp() {
    if(toBeFlushed!=null)
        try {
            toBeFlushed.flush();
        } catch (IOException e) {
            // ignore
        }
    if(toBeClosed!=null)
        try {
            toBeClosed.close();
        } catch (IOException e) {
            // ignore
        }
    toBeFlushed = null;
    toBeClosed = null;
}

方法 write(Object obj, XmlOutput out, Runnable postInitAction) 调用 finally 子句中的清理方法,并且正在发生刷新。但是在这种清理方法中,如果发生任何 IOException,则在刷新时,它们会忽略该异常。

我们想知道,这些段是否生成了损坏的 XML,因为它不会抛出异常而只是吃掉异常。

我们还在 XML 序列化器的 API 文档中找到了以下语句。

类:org.apache.xml.serialize.XMLSerializer

如果在序列化过程中发生 I/O 异常,序列化器不会直接抛出异常,只会在序列化结束时抛出异常(DOM 或者 SAX 的 DocumentHandler.endDocument() 都可以。

感谢任何帮助。

问候, 马玉兰

【问题讨论】:

  • 问题是间歇性的。当我们重新生成文件时,就生成成功了。

标签: java xml serialization jaxb ioexception


【解决方案1】:

IOException 不会被忽略,它被包裹在 MarshalException 中并被重新抛出。您收到的MarshalException 中应该存在根本问题。

【讨论】:

  • 由于代码中的 catch 子句中没有任何内容,它们是如何包装到 marshallexception 中的?此外,我们在调用者中没有任何异常
猜你喜欢
  • 2018-03-24
  • 1970-01-01
  • 2011-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多