Java 关闭XmlValidatingMessageSelector中的DTD加载和验证
如果Java 关闭XmlValidatingMessageSelector中的DTD加载和验证,java,spring-integration,Java,Spring Integration,如果,如何防止在XmlValidatingMessageSelector中加载(和验证)DTD!DOCTYPE节是否存在于Spring集成中传入的XML中 更新 实际上,在我们的SI配置中,我们有这个过滤器配置 @Bean public MessageSelector cageXmlValidator() { XmlValidatingMessageSelector selector = new XmlValidatingMessageSelector( new
,如何防止在XmlValidatingMessageSelector
中加载(和验证)DTD!DOCTYPE
节是否存在于Spring集成中传入的XML中
更新
实际上,在我们的SI配置中,我们有这个过滤器配置
@Bean
public MessageSelector cageXmlValidator() {
XmlValidatingMessageSelector selector = new XmlValidatingMessageSelector(
new ClassPathResource("/CageMessage.xsd"),
XmlValidatingMessageSelector.SchemaType.XML_SCHEMA);
selector.setThrowExceptionOnRejection(true);
return selector;
}
并以这种方式在我们的流程中使用它
@Bean
public IntegrationFlow processorFlow(
...
MessageSelector cageXmlValidator,
Unmarshaller cageXmlUnmarshaller,
...) {
return IntegrationFlows
.from(cageInputChannel())
...
.filter(cageXmlValidator)
.transform(new UnmarshallingTransformer(cageXmlUnmarshaller))
...
.channel(cageOutputChannel())
.get();
}
我也尝试了这个xmlvalitingmessageselector
定义,但它不起作用
@Bean
public MessageSelector cageXmlValidator() throws Exception {
XmlValidatingMessageSelector selector = new XmlValidatingMessageSelector(
new ClassPathResource("/CageMessage.xsd"),
XmlValidatingMessageSelector.SchemaType.XML_SCHEMA);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
selector.setConverter(new DefaultXmlPayloadConverter(factory));
selector.setThrowExceptionOnRejection(true);
return selector;
}
我有这样一个测试用例:
@Test
public void testValidMessage() throws Exception {
Document doc = XmlTestUtil.getDocumentForString("<!DOCTYPE greeting SYSTEM \"greeting.dtd\"><greeting>hello</greeting>");
GenericMessage<Document> docMessage = new GenericMessage<Document>(doc);
PollableChannel validChannel = ac.getBean("validOutputChannel", PollableChannel.class);
MessageChannel inputChannel = ac.getBean("inputChannelA", MessageChannel.class);
inputChannel.send(docMessage);
assertNotNull(validChannel.receive(100));
}
最新的加载外部dtd
功能正是我所需要的
这样,您的应用程序需要在验证之前先为XML创建<代码>文档<代码>,并使用这些代码为
DocumentBuilderFactory
的自定义DefaultXmlPayloadConverter
对我们的有效负载无效:
validationExceptions = this.xmlValidator.validate(this.converter.convertToSource(message.getPayload()));
其中,convertToSource()
看起来像:
public Source convertToSource(Object object) {
Source source = null;
if (object instanceof Source) {
source = (Source) object;
}
else if (object instanceof Document) {
source = new DOMSource((Document) object);
}
else if (object instanceof String) {
source = new StringSource((String) object);
}
else {
throw new MessagingException("unsupported payload type [" + object.getClass().getName() + "]");
}
return source;
}
正如您所看到的,没有人调用DocumentBuilderFactory
我建议您使用一个.transform()
前端过滤器(cageXmlValidator)
将您的负载
转换为带有自定义DocumentBuilderFactory
的文档
对象
鉴于我们不能影响javax.xml.validation.Validator
的内部结构,我认为从验证器调用convertToDocument()
并将其包装到DOMSource
中是一个很好的折衷方案。这样,您的DefaultXmlPayloadConverter
确实会产生效果
可以自由地提出一个JRIa或者甚至考虑贡献。
谢谢你指出这一点 多谢各位。我会试试。。。哪里是
XmlTestUtil
class?。但这不应该困扰您,因为它没有我在这里向您展示的代码。提供的解决方案不起作用。看起来setFeature
设置不会影响在xmlvalidatengmessageselector
内部创建的解析器。当然不会,因为它是外部DocumentBuilderFactory
实例的一部分,与XmlValudator
内部完全无关。你应该分享一些代码,从我们这边复制,最好有一些StackTrace的问题。尽可能多的信息是非常有用的。谢谢,请参阅使用我的SI配置更新问题定义
public Source convertToSource(Object object) {
Source source = null;
if (object instanceof Source) {
source = (Source) object;
}
else if (object instanceof Document) {
source = new DOMSource((Document) object);
}
else if (object instanceof String) {
source = new StringSource((String) object);
}
else {
throw new MessagingException("unsupported payload type [" + object.getClass().getName() + "]");
}
return source;
}