【问题标题】:Spring and CastorMarshaller: add namespace to XML rootSpring 和 CastorMarshaller:将命名空间添加到 XML 根
【发布时间】:2012-02-21 17:18:19
【问题描述】:

我的 Java 应用程序尝试从 Web 服务获取信息。 XML请求需要在XML根元素(类名)中指定命名空间,但标签(类字段)的命名空间需要为空(null),否则webservice拒绝请求。

我必须使用带有 CastorMarshaller 的 Spring 3.0 和 Spring WS 2.0(当前使用 Castor 版本 1.3.1)来将我的 Java 对象编组/解组到 XML 中。

请注意以下代码 sn-ps 中的 __PREFIX____NAMESPACE__ 位置。

所需的编组输出 (即所需生成的 SOAP 请求)

<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-env:Header xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" />
    <soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
        <__PREFIX__:className xmlns:__PREFIX__="__NAMESPACE__">
            <fieldName>fieldValue</fieldName>
        </__PREFIX__:className>
    </soap-env:Body>
</soap-env:Envelope>

当前编组的输出(即生成的 SOAP 请求)

不添加命名空间

<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-env:Header xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" />
    <soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
        <className>
            <fieldName>fieldValue</fieldName>
        </className>
    </soap-env:Body>
</soap-env:Envelope>

或将命名空间添加到所有元素

<?xml version="1.0" encoding="UTF-8"?>
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
    <soap-env:Header xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/" />
    <soap-env:Body xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
        <__PREFIX__:className xmlns:__PREFIX__="__NAMESPACE__">
            <__PREFIX__:fieldName xmlns:__PREFIX__="__NAMESPACE__">fieldValue</__PREFIX__:fieldName>
        </__PREFIX__:className>
    </soap-env:Body>
</soap-env:Envelope>

都被 web 服务拒绝。

我的配置

CastorMarshaller beanapplicationContext.xml

<bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller">
    <property name="mappingLocation" value="classpath:castor-mapping.xml" />
    <property name="ignoreExtraAttributes" value="true" />
    <property name="ignoreExtraElements" value="true" />
    <property name="namespaceMappings">
        <map>
            <entry key="__PREFIX__" value="__NAMESPACE__" />
        </map>
    </property>
</bean>

Castor 映射文件 castor-mapping.xml

不添加命名空间(castorMarshaller bean 到 namespaceMappings 中指定的命名空间应该添加到根目录)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
                         "http://castor.org/mapping.dtd">
<mapping>
    <class name="some.package.ClassName">
        <map-to xml="className">
        <field name="fieldName" type="string">
            <bind-xml name="fieldName" node="element" />
        </field>
    </class>
</mapping>

或将命名空间添加到所有元素

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapping PUBLIC "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
                         "http://castor.org/mapping.dtd">
<mapping>
    <class name="some.package.ClassName">
        <map-to xml="className" ns-uri="__NAMESPACE__" ns-prefix="__PREFIX__">
        <field name="fieldName" type="string">
            <bind-xml name="fieldName" node="element" />
        </field>
    </class>
</mapping>

【问题讨论】:

    标签: java xml spring xml-namespaces castor


    【解决方案1】:

    由于我面临同样的问题,我正在考虑的解决方案如下:

    1. 创建一个扩展 EndpointInterceptorAdapter 的拦截器
    2. 覆盖 handleResponse 方法
    3. 通过直接访问或使用转换器修改为soap消息

    公共类 MyEndpointInterceptorAdapter 扩展 EndpointInterceptorAdapter{

          @Override
          public boolean handleResponse(MessageContext msgContext, Object endpoint) throws IOException {
    
              WebServiceMessage responseMsg = msgContext.getResponse();
              SoapMessage soapMsg = (SoapMessage) responseMsg;
    
              if(soapMsg!=null){
                  SoapEnvelope soapEnvelope=soapMsg.getEnvelope();
    
                  if(soapEnvelope!=null){
    
                      SoapBody soapbody=soapEnvelope.getBody();
    
                      if(soapbody!=null){
    
                          Source bodySource=soapbody.getSource();
                          if(bodySource instanceof DOMSource){
                              DOMSource bodyDomSource=(DOMSource)bodySource;
                              Node bodyNode=bodyDomSource.getNode();
    
                              if(bodyNode!=null){
                                  NodeList bodyNodeList=bodyNode.getChildNodes();
    
                                  if(bodyNodeList.getLength()!=0){
                                      Element root=(Element)bodyNodeList.item(0);
                                      root.setAttribute("xmlns:ns", "YourURI");
                                      root.setPrefix("ns");               
                                  }
                              }       
                          }
                      }
                  }
              }
    
              return true;
          }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2017-09-21
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      相关资源
      最近更新 更多