【问题标题】:Allow CXF webservice receive XML as string - CDATA允许 CXF webservice 接收 XML 作为字符串 - CDATA
【发布时间】:2014-10-08 18:07:40
【问题描述】:

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

根据 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>

【问题讨论】:

  • 如果你想把xml当作字符串,我相信CDATA是唯一的方法。
  • 我在 Phase.RECEIVE 实现了一个拦截器,用 CDATA 块包装所有值。
  • 太棒了。您能否提供您的实现以供将来参考?是这样的cxf.547215.n5.nabble.com/… 吗?
  • 我已经发布了我的实现。

标签: xml web-services xsd cxf


【解决方案1】:

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

   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;
            }

        }

【讨论】:

  • 您可以选择自己的答案作为解决方案。
  • 谢谢,但我想看看是否有人能提供更好的解决方案。
猜你喜欢
  • 2012-07-18
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 2011-05-31
  • 2014-06-21
  • 2014-01-03
  • 2012-03-07
相关资源
最近更新 更多