允许CXF Web服务以字符串形式接收XML - CDATA

时间:2014-08-14 23:19:13

标签: xml web-services xsd cxf

我的任务是开发一个webservice代理,它实现与目标webservice(原始webservice)相同的wsdl。我的问题是,&#34; String_1&#34;字段包含xml字符串,例如<String_1>xml string here...</String_1>,其中包含尖括号(&#34;&lt;&gt;&#34;)。

根据xsd:string,正确的行为是抛出错误。我使用wsdl2java生成代码,它按预期工作。

但是,目标Web服务可以接受该消息而不会抛出异常,例如将"<dummy />"视为字符串。

我想知道如何绕过验证检查?或者可能覆盖一些拦截器以在有效负载中添加"<!CDATA"

我尝试过如下设置参数,但它只会抛出不同类型的异常:

   <jaxws:properties>     
      <entry key="faultStackTraceEnabled" value="true" />
      <entry key="exceptionMessageCauseEnabled" value="true" />
      <entry key="schema-validation-enabled" value="false" />
      <entry key="set-jaxb-validation-event-handler" value="false" />  
   </jaxws:properties>

请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:man="http://mantra.com/mantraws">
   <soapenv:Header/>
   <soapenv:Body>
      <man:getList>

         <String_1><dummy/></String_1>

      </man:getList>
   </soapenv:Body>
</soapenv:Envelope>

WSDL:

<part name='String_1' type='xsd:string'></part>

响应:

  <soap:Fault>
     <faultcode>soap:Client</faultcode>
     <faultstring>Unmarshalling Error: unexpected element (uri:"", local:"dummy"). Expected elements are (none)</faultstring>
     <detail> ... </detail>
  </soap:Fault>

1 个答案:

答案 0 :(得分:2)

这是我的实施。我知道有很多地方需要改进(例如使用效率&#34; replaceAll()&#34;方法)。如果有更好的实施,请告诉我。

   public class CDATAInInterceptor extends AbstractPhaseInterceptor<Message> {
            public CDATAInInterceptor() {
                super(Phase.RECEIVE);
            }

            @Override
            public void handleMessage(Message message) {
                message.put(Message.ENCODING, "UTF-8");
                InputStream is = message.getContent(InputStream.class);

                if (is != null) {
                    CachedOutputStream cos = new CachedOutputStream();
                    try {
                        IOUtils.copy(is, cos);
                        String soapMessage = new String(cos.getBytes());
                        cos.flush();
                        cos.close();
                        is.close();

                        // escape the content by wrapping it with CDATA block
                        // hard coded tag name that contains xml string
                        String newSoapMessage = escapeContent(soapMessage, new String[]{"tag_1", "tag_2"});

                        InputStream newIs = new ByteArrayInputStream(newSoapMessage.getBytes());
                        message.setContent(InputStream.class, newIs);

                    } catch (IOException ioe) {
                        ioe.printStackTrace();
                    }
                }
            }

            // this methods will wrap "CDATA" around content of supplied tagNames
            private String escapeContent(final String xmlString, String[] tagNames) {
                String newXmlString = xmlString;

                for (String tagName : tagNames) {

                    // start tag
                    newXmlString = newXmlString.replaceAll("<" + tagName + ">", "<"+ tagName + "><![CDATA[");
                    // close tag
                    newXmlString = newXmlString.replaceAll("</" + tagName + ">", "]]></" + tagName + ">");
                }

                return newXmlString;
            }

        }