我已经在这件事上用头撞墙好几天了。我们是 使用 Spring Web 服务 2.1.3.RELEASE 并且我添加了一个简单的子类 PayloadValidatingInterceptor 用于捕获 XSD 架构验证错误。
配置:
<bean id="xsdValidationInterceptor" class="foo.bar.endpoint.interceptors.XSDValidatingInterceptor">
<property name="schemas">
<list>
<value>classpath:/xsd/requestName.xsd</value>
</list>
</property>
<property name="validateRequest" value="true"/>
<property name="validateResponse" value="true"/>
</bean>
XsdValidationInterceptor 重写handleRequestValidationErrors:
@Override
protected boolean handleRequestValidationErrors(
MessageContext messageContext, SAXParseException[] errors)
throws TransformerException {
if ( getAddValidationErrorDetail() ) {
messageContext.setProperty(MessageContextConstants.KEY_SCHEMA_ERRORS, errors);
}
return true;
}
到目前为止一切顺利。这个问题是从返回的消息的格式 Xerces 解析器。问题是,我想要字段名称和行/列号 错误发生的地方,而不必从长字符串中挖掘出来 对于不同的错误是不同的。看起来应该很简单,但 Spring 确实如此 似乎并不容易。一旦错误出现在handleRequestValidationErrors处 例程中,异常消息已被格式化。
具体来说,我想替换 XMLErrorReporter 或 XMLErrorReporter 在模式 validator 中使用的 MessageFormatter Spring 创造的。 Xerces 提供了一个标准属性来替换 错误报告者;然而,Spring 并没有让这一切变得容易。它使用一个 硬编码的 JAXP 工厂称为 Jaxp13ValidatorFactory 来创建 一个 XMLValidator 对象,它本质上包装了一个 在每个请求处理时 Xerces validator 。 XMLValidator 没有 允许在 validator 实现上设置属性 创造。
我查看了 Xerces 以及其他的自定义配置 可能的黑客攻击,此时我唯一能想到的是 覆盖 XsdValidationInterceptor 中的handleRequest 例程 创建我自己的 validator ,我可以根据需要进行配置。
大家有更好的想法吗?
这与此处提出的问题相同,但遗憾的是没有得到回答:
How can I provide custom error messages using JAXP DocumentBuilder?
最佳答案
好吧,在做了更多研究之后,这个问题不是 Spring 的错。似乎是 Java 中 Sax 解析方式演变的产物。
基本架构是 Spring -> JAXP -> Parser Provider (Xerces)。
JAXP 接口(interface)允许设置功能,但不提供必要的功能 控制来替换 Xerces 解析器中的 ErrorReporter 组件,也不 定制它。定制将涉及构建 Xerces 解析器实例 使用自定义 ErrorReporter 组件并覆盖 Xerces 实现 这是 JVM 的一部分。
当我们尝试交付产品时,这根本不是一个可行的替代方案 在我们可能无法控制的环境中的 JVM 之上。底线是我们有 接受这些消息的本来面目。
关于java - 替换 Spring PayloadValidatingInterceptor 中的 XML MessageFormatter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26789615/