【发布时间】:2014-07-02 21:04:55
【问题描述】:
我有一个从 xml 文件获取输入流的网络服务。现在,我想验证并使用相同的输入流读取它。我使用标记并重置它。
在 Glassfish 和 Websphere 上运行良好。但是当我使用 openEJB 运行集成测试时,流将在验证后关闭。我可以在一个简单的例子中重现它。
我怎样才能更好地实现它?验证器实现总是相同的。但是每个环境都使用另一种输入流实现。
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());
}
}
}
例外:
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 吗?
-
我们通过 REST 服务获取 XML 文件作为字符串。我用来创建输入流的那个字符串。上面的示例仅用于演示行为。
-
请展示您从字符串创建 InputStream 的代码。请注意,将内容加载到任意长的字符串中通常不是一个好主意。首先将其复制到一个临时文件(可能使用java.nio.file.Files.copy(...))。
标签: java xml validation xsd inputstream