3

Java アプリケーションが Web サービスから情報を取得しようとしています。XML 要求には、XML ルート要素 (クラス名) で指定された名前空間が必要ですが、タグ (クラス フィールド) の名前空間は空 (null) である必要があります。そうでない場合、Web サービスは要求を拒否します。

Spring 3.0 および Spring WS 2.0 を CastorMarshaller (現在は Castor バージョン 1.3.1 を使用) と共に使用して、Java オブジェクトを 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>

どちらも 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

名前空間を追加しない ( castorMarshallerBean スルーで指定された名前空間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>
4

1 に答える 1

2

私は同じ問題に直面しているので、私が検討している解決策は次のとおりです。

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

}
于 2013-01-31T23:47:46.220 に答える