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创建<代码>文档<代码>,并使用这些代码为DoBuffBueDeWorksUng/<代码> < < /P> 更新

插入带有适当的
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;
}