java - 使用相同的输入流验证并读取

标签 java xml validation xsd inputstream

我有一个网络服务,它从 xml 文件获取输入流。现在,我想用相同的输入流验证并读取它。我使用标记并重置它。

在 Glassfish 和 Websphere 上它运行良好。但是当我使用 openEJB 运行集成测试时,流将在验证后关闭。我可以在一个简单的例子中重现它。

如何更好地实现它? validator 实现始终相同。但每个环境都使用输入流的另一种实现。

public class XMLReader {
public static void main(String[] args) {
    try {
        XMLReader reader = new XMLReader();
        InputStream stream = new BufferedInputStream(new FileInputStream(
                new File("myXML.xml")));
        reader.read(stream);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void read(InputStream xmlInputStream) throws SAXException,
        IOException {
    if (xmlInputStream.markSupported()) {
        xmlInputStream.mark(0);
        validateXML(xmlInputStream);
        xmlInputStream.reset();
        readXML(xmlInputStream);
    }
}

private void readXML(InputStream xmlInputStream) {
    // READ xmInputStream with STAX, JAXB, etc. whatever

}

private void validateXML(InputStream xmlInputStream) throws SAXException,
        IOException {
    Source schemaFile = new StreamSource(new File("myXSD.xsd"));
    Source xmlFile = new StreamSource(xmlInputStream);
    SchemaFactory schemaFactory = SchemaFactory
            .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
    Schema schema = schemaFactory.newSchema(schemaFile);
    Validator validator = schema.newValidator();
    try {
        validator.validate(xmlFile);
        System.out.println("is valid");
    } catch (SAXException e) {
        System.out.println("is NOT valid");
        System.out.println("Reason: " + e.getLocalizedMessage());
    }
}
}

异常(exception):

  java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145)
at java.io.BufferedInputStream.reset(BufferedInputStream.java:414)
at xmltest.XMLReader.read(XMLReader.java:36)
at xmltest.XMLReader.main(XMLReader.java:27)

最佳答案

不幸的是,XML 解析器在完成读取后关闭流。我不明白为什么它真的会这样做,我不会建议任何人关闭他们不拥有的流。可能有一个我无法这么快理解的原因。

无论如何,您可以做的是拥有一个 BufferedInputStream,它不会关闭包装的 InputSteam:

public static void main(String[] args) {
    try (FileInputStream in = new FileInputStream(new File("myXML.xml"))){
        XMLReader reader = new XMLReader();
        InputStream stream = new BufferedInputStream(in) {
            @Override
            public void close() throws IOException {
               // don't close
            }
        };
        reader.read(stream);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

关于java - 使用相同的输入流验证并读取,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23660919/

相关文章:

java - Spring Boot - 从 2.2.5 升级到 2.3.0 后验证停止工作

ajax - AJAX 上的 Parsley.js 触发错误

Java套接字文件发送

java - 如何将 Date.getTime() 转换为小时并计算差异

java - 逆向工程随机数生成器

c# - 在 Windows Phone 上检测流或字节数组编码

java - 如何使用 Spring Boot 从 S3 下载 json 文件?

xml - 模式验证包含 bool 值的 xml

java - XML 配置大小为 0

jQuery 验证插件 - 仅在可见时验证隐藏元素