验证并使用相同的输入流读取 [英] Validate AND read with the same inputstream
问题描述
在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解析器在完成读取后就关闭了流.我不明白为什么这样做确实如此,并且我不建议任何人关闭他们不拥有的信息流.可能有一个原因让我无法快速掌握.
无论如何,您可以做的是拥有一个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();
}
}
i have a webservice which get an inputstream from a xml- file. Now, i want validate AND read it with the same inputstream. I use mark and reset for it.
On Glassfish and Websphere it works fine. But when i run my integration tests with openEJB, the stream will be closed after validation. I can reproduce it in a simple example.
How can i realize it better? The Validator Implementation is always the same. But every environment use another implementation of inputstream.
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)
Unfortunately, the XML parser closes the stream upon finishing reading. I don't understand why it does that really and I wouldn't recommend anyone to closing streams that they don't own. There might be a reason that I couldn't grasp that quickly.
Anyways, what you could do is having a BufferedInputStream, that does not close the wrapped 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();
}
}
这篇关于验证并使用相同的输入流读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!