我有这个方法:
override fun read(): Verification? {
var fileVerifcation: FileVerification? = null
try {
val files = remoteFileOperations.list(path)
val fileName = files
.map { it.filename }
.firstOrNull { name ->
remoteFileOperations.get("$path/$name") {
it.use { text ->
//I've added this --->>> validate(text, XSD_FILE)
fileVerifcation = xmlParser.parse(text)
}
}
}
if (fileName != null) {
return Verification(fileName)
}
return null
} catch (e: MessagingException) {
throw ReceivedException("Cannot read file", e)
}
}
}
其中
remoteFileOperations
是: private val remoteFileOperations: RemoteFileOperations<DirEntry>
问题是添加此代码片段后
validate(text, XSD_FILE)
读取XML文件时出现错误,因为流在读取操作完成之前已关闭。
添加的代码用于根据 xsd 验证 xml,其中
text
是 xml 文件,XSD_FILE 是 xsd 文件的路径。
我不知道
validate
方法中会发生什么,引发如下错误:
Caused by: org.springframework.messaging.MessagingException: Failed to execute on session
Caused by: com.fasterxml.jackson.core.JsonParseException: read(xml/file_01.XML) stream closed
Caused by: java.io.IOException: read(xml/file_01.XML) stream closed
突然无法读取这些 xml 文件,因为流已终止?但为什么呢?
class Validate {
companion object {
@Throws(IOException::class, SAXException::class)
fun validate(xml: InputStream, xsd: File): IsValid {
val errorHandler = XMLErrorHandler()
val validator = init(xsd)
validator.errorHandler = errorHandler
validator.validate(StreamSource((xml)))
return errorHandler.getResult()
}
@Throws(SAXException::class)
private fun init(xsd: File): Validator {
val factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
val schema = factory.newSchema(xsd)
return schema.newValidator()
}
}
}
我尝试做这样的事情:
validate(content.readBytes().inputStream(),XSD_FILE)
但是错误是相似的,并且还出现了新的错误:
Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected EOF in prolog
可能与
upload
方法有关,该方法将 xml 文件上传到 sftp 服务器并以 InputStream
作为参数。就像验证方法也需要一个 InputStream
并且也许创建了一些东西来阻止这个?
fun upload(input: InputStream, file: String) {
remoteFileOperations.execute { session ->
input.use {
val headers = getHeaders(file)
removeIfExists(file)
remoteFileOperations.send(GenericMessage(it, headers))
val client = session.clientInstance as SftpClient
val attributes = client.stat("${path}/$file")
attributes.permissions = Integer.parseInt("0660", 8)
client.setStat("${path}/$file", attributes)
}
}
}
基于 XSD 的 XML 验证由您正在执行的
validator.validate(StreamSource((xml)))
调用进行调用。
此调用将导致调用
StreamValidatorHelper.validate(Source, Result)
,最终导致调用 XMLParserConfiguration.parse(XMLInputSource)
方法。
最后一个方法,根据 javadoc 的说法:
当该方法返回时,解析器打开的所有字符流和字节流都将被关闭。
因此,用于根据 XSD 验证 XML 的
inputStream
将在验证继续后关闭。
您需要更改代码才能使用两个输入流(一个用于验证,一个用于解析)。也许这个SO线程可以有所帮助。