java - 为什么 Unmarshaller 行为不一致?

标签 java xsd-validation jaxb2 spring-web

我创建了一个简单的网络服务 (spring-web),用于验证关于 XSD 的传入 XML,如果发生任何验证错误,它们应该返回给请求者。

下面的代码完成了它的工作......

@PostMapping(path = "/test", consumes = MediaType.APPLICATION_XML_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> method2(@RequestBody Source request) throws IOException, JAXBException, SAXException {

    final URL schemaUrl = resourceLoader.getResource("classpath:test.xsd").getURL();
    final CumulatingErrorHandler errorHandler = new CumulatingErrorHandler();
    final Schema schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
            .newSchema(schemaUrl);
    final ValidationEventCollector validationEventCollector = new MyValidationEventCollector();

    final Unmarshaller unmarshaller = JAXBContext
            .newInstance(IncomingRequestModel.class)
            .createUnmarshaller();
    unmarshaller.setEventHandler(validationEventCollector);
    unmarshaller.setSchema(schema);

    final IncomingRequestModel requestModel = (IncomingRequestModel) unmarshaller.unmarshal(request);

    if (validationEventCollector.hasEvents()) {
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
        return new ResponseEntity<>(validationEventCollector.getEvents(), responseHeaders, HttpStatus.BAD_REQUEST);
    }

    /* do stuff */
}

...但是,出于一个奇怪的原因,它正在“累积”处理的请求之间的错误。在第一次请求期间,返回 3 个错误。同样,对于第二个和第三个请求。然而,在第 4 次请求时,UnmarshallingContext 中的计数器达到零(从 10 开始倒计时)并返回以下错误:

Errors limit exceeded. To receive all errors set com.sun.xml.internal.bind logger to FINEST level.

在第五次请求时,它不会抛出任何验证错误!只是为了说明 - 所有请求都完全相同。

为什么 UnmarhsallingContext 有一个静态计数器来阻止第 5 个请求被验证?我该如何克服这个问题?

我的构建配置:Spring boot 1.4.3.RELEASE,gradle deps:

dependencies {
    compile('org.springframework.boot:spring-boot-starter-amqp')
    compile('org.springframework.boot:spring-boot-starter-data-redis')
    compile('org.springframework.boot:spring-boot-starter-jersey')
    compile('org.springframework.boot:spring-boot-starter-web')

    compile("com.fasterxml.jackson.core:jackson-databind")
    compile("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")

    compileOnly('org.projectlombok:lombok:1.16.12')

    compile("net.sf.dozer:dozer:5.5.1")
    compile("net.sf.dozer:dozer-spring:5.5.1")

    compile("org.apache.commons:commons-lang3:3.5")

    testCompile('org.springframework.boot:spring-boot-starter-test')
}

最佳答案

我今天遇到了同样的错误,并通过应用 JAXB 的 Messages.properties 中的建议克服了这个错误: 在调用解码之前添加 java.util.logging.Logger.getLogger("com.sun.xml.internal.bind").setLevel(Level.FINEST);

关于java - 为什么 Unmarshaller 行为不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41852874/

相关文章:

java - 使用 Java 8 流,如何将 Map<String, Map<String, List<Person>>> 转换为 Map<Integer, Map<String, Integer>>?

c# - 针对游戏的替代 Java 或 C# UI 库

java - 在 JSP 中集成 Birt 报告

java - 如何使用 xsd 验证 xml?

java - jaxb2 maven 插件,在单独的标签中定义多个模式文件

java - 在日出/日落 Web 服务的 url 中使用 DatePicker 中的日期

java - 在 XSD 中进行与选择类似的序列会引发 "' 违反“唯一粒子属性”异常

java - 使用 XMLReader 根据 XSD 验证 XML

java - 具有 2 个根元素的 XSD(一次 1 个)