Spring和CastorMarshaller:将命名空间添加到XML根目录中



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

我必须将Spring 3.0和Spring WS 2.0与CastorMarshaller一起使用(目前使用的是Castor 1.3.1版本),才能将我的Java对象编组到XML中/从XML中取消编组。

请注意以下代码段中的__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>

两者都被网络服务拒绝。

我的配置

applicationContext.xml 中的CastorMarshaller bean

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

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

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

相关内容

  • 没有找到相关文章