在Spring WS中使用AxiomSoapMessageFactory时,使用UndeclaredPrefix进行XSD验证失败

时间:2016-01-06 12:52:43

标签: spring-ws axiom

我正在使用spring-ws 2.2.3构建契约优先的SOAP Web服务。我的XML Schema使用扩展,在XML请求中导致xsi:type=属性。由于某些响应可能非常大(30MB),我正在使用AxiomSoapMessageFactory而不是默认的SaajSoapMessageFactory,如Spring WS docs中所述。我使用PayloadValidatingInterceptor验证传入的请求:

PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
interceptor.setSchema(new ClassPathResource("format-service.xsd"));
interceptor.setValidateRequest(true);
interceptor.setValidateResponse(false); 

我的问题是我得到了虚假的验证错误,具体取决于XML声明命名空间的位置:如果它在有效负载中声明,那么一切正常:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
   <soapenv:Header/>
   <soapenv:Body>
      <sch:formatRequest xmlns:sch="http://example.com/springws/extension/schema">
         <sch:value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="sch:currencyType">
           <sch:amount>1000</sch:amount>
           <sch:currency>EUR</sch:currency>
         </sch:value>
      </sch:formatRequest>
   </soapenv:Body>
</soapenv:Envelope>

但是,只要我将sch命名空间声明移动到Envelope:

<soapenv:Envelope xmlns:sch="http://example.com/springws/extension/schema" ...>

验证失败,我收到SOAP错误:

<faultcode>soapenv:Client</faultcode>
<faultstring xml:lang="en">Validation error</faultstring>
<detail>
    <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
    <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-elt.4.1: The value 'sch:currencyType' of attribute 'http://www.w3.org/2001/XMLSchema-instance,type' of element 'sch:value' is not a valid QName.</spring-ws:ValidationError>
    <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-type.2: The type definition cannot be abstract for element sch:value.</spring-ws:ValidationError>
    <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">UndeclaredPrefix: Cannot resolve 'sch:currencyType' as a QName: the prefix 'sch' is not declared.</spring-ws:ValidationError>
    <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-attribute.3: The value 'sch:currencyType' of attribute 'xsi:type' on element 'sch:value' is not valid with respect to its type, 'QName'.</spring-ws:ValidationError>
    <spring-ws:ValidationError xmlns:spring-ws="http://springframework.org/spring-ws">cvc-complex-type.2.1: Element 'sch:value' must have no character or element information item [children], because the type's content type is empty.</spring-ws:ValidationError>
</detail>

它似乎是AxiomSoapMessageFactory / Axiom实现中的一个错误(命名空间上下文丢失),因为两个请求在使用SaajSoapMessageFactory时都能正常运行。请注意,验证仅在xsi:type=属性上失败。正确识别元​​素的相同名称空间。

由于大响应的高内存消耗,我无法使用SaajSoapMessageFactory。我发现了Spring forumSO中描述的类似问题,但没有解决方法。谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

原因是Spring-WS使用OMContainer#getXMLStreamReader()。相反,它应该使用OMContainer#getXMLStreamReader(boolean, OMXMLStreamReaderConfiguration)并将preserveNamespaceContext属性设置为true对象中的OMXMLStreamReaderConfiguration

您应该为Spring-WS提交错误,甚至更好,修复问题并提交拉取请求。