错误 |无法加载 json 架构! java.io.IOException:流关闭
ERROR | Failed to load json schema! java.io.IOException: Stream closed
我正在尝试根据其模式验证 json 对象,但我的模式文件非常大(386 行)。
这是我在 java 中的代码行:
public static void jsonSchemValidator() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();;
InputStream jsonStream = inputStreamFromClasspath("/json/pickevent1.json");
InputStream schemaStream = inputStreamFromClasspath("/json/schemaeg.json");
JsonNode json = objectMapper.readTree(jsonStream);
JsonNode jsonSchema = objectMapper.readTree(schemaStream);
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(jsonSchema));
JsonSchema schema = validatorFactory.getSchema(schemaStream);
Set<ValidationMessage> validationResult = schema.validate(json);
if (validationResult.isEmpty()) {
System.out.println("no validation errors :-)");
} else {
validationResult.forEach(vm -> System.out.println(vm.getMessage()));
}
jsonStream.close();
schemaStream.close();
}
}
IndputStream 的代码:
public static InputStream inputStreamFromClasspath(String path) {
return Utils.class.getResourceAsStream(path);
}
以上适用于小型架构。但它给出了一个错误:
ERROR | Failed to load json schema!
java.io.IOException: Stream closed
这是堆栈跟踪:
ERROR | Failed to load json schema!
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:539)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.detectEncoding(ByteSourceJsonBootstrapper.java:133)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.constructParser(ByteSourceJsonBootstrapper.java:256)
at com.fasterxml.jackson.core.JsonFactory._createParser(JsonFactory.java:1655)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1083)
at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:3056)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:315)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:324)
at common.Utils.jsonSchemValidator(Utils.java:105)
at picking.begin.TestAssertionForPickBegin.before(TestAssertionForPickBegin.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
at org.testng.TestRunner.beforeRun(TestRunner.java:529)
at org.testng.TestRunner.run(TestRunner.java:497)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
com.networknt.schema.JsonSchemaException: java.io.IOException: Stream closed
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:319)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:324)
at common.Utils.jsonSchemValidator(Utils.java:105)
at picking.begin.TestAssertionForPickBegin.before(TestAssertionForPickBegin.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
at org.testng.TestRunner.beforeRun(TestRunner.java:529)
at org.testng.TestRunner.run(TestRunner.java:497)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
Caused by: java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:539)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.detectEncoding(ByteSourceJsonBootstrapper.java:133)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.constructParser(ByteSourceJsonBootstrapper.java:256)
at com.fasterxml.jackson.core.JsonFactory._createParser(JsonFactory.java:1655)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1083)
at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:3056)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:315)
... 26 more
我对 java 很陌生。任何建议都会有所帮助。谢谢。
我认为问题在于您从 InputStream schemaStream
读取了两次。
您先将其传递给 objectMapper.readTree(...)
,然后再将相同的 InputStream 传递给 validatorFactory.getSchema(...)
。
一般来说,这样做是一件坏事,因为第一次使用流可能会使它耗尽(即它没有更多数据到 return)或关闭,就像你的情况一样.老实说,我很惊讶您没有在小模式中得到类似的行为:我猜这是 InputStream 的一个怪癖,它从对 .getResourceAsStream(...)
的调用中得到 returned。
尝试从资源中打开一个新的 InputStream,而不是第二次尝试从其中读取。我还调整了您的代码以使用 try-with-resources,这样即使在抛出异常的情况下 InputStreams 也会关闭:
public static void jsonSchemValidator() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
try (InputStream jsonStream = inputStreamFromClasspath("/json/pickevent1.json")) {
JsonNode json = objectMapper.readTree(jsonStream);
JsonSchemaFactory validatorFactory;
try (InputStream schemaStream = inputStreamFromClasspath("/json/schemaeg.json")) {
JsonNode jsonSchema = objectMapper.readTree(schemaStream);
validatorFactory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(jsonSchema));
}
try (InputStream schemaStream = inputStreamFromClasspath("/json/schemaeg.json")) {
JsonSchema schema = validatorFactory.getSchema(schemaStream);
Set<ValidationMessage> validationResult = schema.validate(json);
if (validationResult.isEmpty()) {
System.out.println("no validation errors :-)");
} else {
validationResult.forEach(vm -> System.out.println(vm.getMessage()));
}
}
}
}
我正在尝试根据其模式验证 json 对象,但我的模式文件非常大(386 行)。
这是我在 java 中的代码行:
public static void jsonSchemValidator() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();;
InputStream jsonStream = inputStreamFromClasspath("/json/pickevent1.json");
InputStream schemaStream = inputStreamFromClasspath("/json/schemaeg.json");
JsonNode json = objectMapper.readTree(jsonStream);
JsonNode jsonSchema = objectMapper.readTree(schemaStream);
JsonSchemaFactory validatorFactory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(jsonSchema));
JsonSchema schema = validatorFactory.getSchema(schemaStream);
Set<ValidationMessage> validationResult = schema.validate(json);
if (validationResult.isEmpty()) {
System.out.println("no validation errors :-)");
} else {
validationResult.forEach(vm -> System.out.println(vm.getMessage()));
}
jsonStream.close();
schemaStream.close();
}
}
IndputStream 的代码:
public static InputStream inputStreamFromClasspath(String path) {
return Utils.class.getResourceAsStream(path);
}
以上适用于小型架构。但它给出了一个错误:
ERROR | Failed to load json schema!
java.io.IOException: Stream closed
这是堆栈跟踪:
ERROR | Failed to load json schema!
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:539)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.detectEncoding(ByteSourceJsonBootstrapper.java:133)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.constructParser(ByteSourceJsonBootstrapper.java:256)
at com.fasterxml.jackson.core.JsonFactory._createParser(JsonFactory.java:1655)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1083)
at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:3056)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:315)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:324)
at common.Utils.jsonSchemValidator(Utils.java:105)
at picking.begin.TestAssertionForPickBegin.before(TestAssertionForPickBegin.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
at org.testng.TestRunner.beforeRun(TestRunner.java:529)
at org.testng.TestRunner.run(TestRunner.java:497)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
com.networknt.schema.JsonSchemaException: java.io.IOException: Stream closed
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:319)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:324)
at common.Utils.jsonSchemValidator(Utils.java:105)
at picking.begin.TestAssertionForPickBegin.before(TestAssertionForPickBegin.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.MethodInvocationHelper.invokeMethodConsideringTimeout(MethodInvocationHelper.java:59)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:458)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:222)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:142)
at org.testng.TestRunner.beforeRun(TestRunner.java:529)
at org.testng.TestRunner.run(TestRunner.java:497)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
Caused by: java.io.IOException: Stream closed
at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:170)
at java.io.BufferedInputStream.read(BufferedInputStream.java:336)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.ensureLoaded(ByteSourceJsonBootstrapper.java:539)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.detectEncoding(ByteSourceJsonBootstrapper.java:133)
at com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper.constructParser(ByteSourceJsonBootstrapper.java:256)
at com.fasterxml.jackson.core.JsonFactory._createParser(JsonFactory.java:1655)
at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:1083)
at com.fasterxml.jackson.databind.ObjectMapper.readTree(ObjectMapper.java:3056)
at com.networknt.schema.JsonSchemaFactory.getSchema(JsonSchemaFactory.java:315)
... 26 more
我对 java 很陌生。任何建议都会有所帮助。谢谢。
我认为问题在于您从 InputStream schemaStream
读取了两次。
您先将其传递给 objectMapper.readTree(...)
,然后再将相同的 InputStream 传递给 validatorFactory.getSchema(...)
。
一般来说,这样做是一件坏事,因为第一次使用流可能会使它耗尽(即它没有更多数据到 return)或关闭,就像你的情况一样.老实说,我很惊讶您没有在小模式中得到类似的行为:我猜这是 InputStream 的一个怪癖,它从对 .getResourceAsStream(...)
的调用中得到 returned。
尝试从资源中打开一个新的 InputStream,而不是第二次尝试从其中读取。我还调整了您的代码以使用 try-with-resources,这样即使在抛出异常的情况下 InputStreams 也会关闭:
public static void jsonSchemValidator() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
try (InputStream jsonStream = inputStreamFromClasspath("/json/pickevent1.json")) {
JsonNode json = objectMapper.readTree(jsonStream);
JsonSchemaFactory validatorFactory;
try (InputStream schemaStream = inputStreamFromClasspath("/json/schemaeg.json")) {
JsonNode jsonSchema = objectMapper.readTree(schemaStream);
validatorFactory = JsonSchemaFactory.getInstance(SpecVersionDetector.detect(jsonSchema));
}
try (InputStream schemaStream = inputStreamFromClasspath("/json/schemaeg.json")) {
JsonSchema schema = validatorFactory.getSchema(schemaStream);
Set<ValidationMessage> validationResult = schema.validate(json);
if (validationResult.isEmpty()) {
System.out.println("no validation errors :-)");
} else {
validationResult.forEach(vm -> System.out.println(vm.getMessage()));
}
}
}
}