Spring и CastorMarshaller: добавить пространство имен в корневой каталог XML - PullRequest
3 голосов
/ 29 января 2012

Мое Java-приложение пытается получить информацию от веб-службы.В запросе XML должно быть указано пространство имен в корневом элементе XML (имя класса), но пространство имен тегов (полей класса) должно быть пустым (null), в противном случае веб-служба отклоняет запрос.

Мне нужно использовать 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>

, которые оба отклоняются веб-службой.

Моя конфигурация

Боб CastorMarshaller in applicationContext.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 до 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 Ответ

2 голосов
/ 01 февраля 2013

Поскольку я сталкиваюсь с той же проблемой, решение, которое я рассматриваю, заключается в следующем:

  1. Создать расширение перехватчика EndpointInterceptorAdapter
  2. Переопределить метод handleResponse
  3. Изменить сообщение мыла путем прямого доступа или использования преобразователя

открытый класс MyEndpointInterceptorAdapter extends 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;
      }

}
...