Что может быть добавлением лишнего xmlns в ответ SOAP?

Я унаследовал веб-сервис, который работал нормально, пока нам не пришлось обновить среду выполнения (с JBOSS/JRE6 до Tomcat7/JRE7). Там не было никакого изменения кода, за исключением pom.xml!

На самом деле он все еще работает нормально, за исключением того, что многие существующие клиенты больше не могут обрабатывать ответ из-за дополнительного атрибута пространства имен, который теперь присутствует в одном из элементов (ответа).

То есть ранее (до миграции) этот элемент (в ответе SOAP) был:

<OurResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
             xsi:noNamespaceSchemaLocation="OurResponse.xsdXMLSchema-instance" 
             ourresponseVersion="M1m2v03" xmlns="">

И сейчас это:

<v01:OurResponse acknowledgementVersion="M1m2v03" 
     xmlns:v01="http://webservice.ourdomain.com/projone/modtwo/M1m2v03">

Поскольку не было никакого изменения кода, я озадачен этим (незначительным, но критическим) изменением в ответе SOAP.

В частности, я пытаюсь понять:

  1. Какая часть системы сборки изменяет этот атрибут пространства имен?
  2. Как мне восстановить его прежнее поведение?
  3. Почему клиенты нарушают такие незначительные изменения? (т.е. содержание ответа идентично!)

Единственные важные изменения, которые я смог заметить в pom.xml:

  1. Добавляем следующие зависимости:

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk16</artifactId>
        <version>1.46</version>
    </dependency>
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.7.4</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>3.0.7.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>net.sf.ehcache</groupId>
                <artifactId>ehcache</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  2. Обновление cxf-rt-frontend-jaxws зависимость от версии 2.2.7 до 2.7.7.

  3. Обновление cxf-rt-transports-http зависимость от версии 2.2.7 до 2.7.7.

  4. Обновление cxf-rt-ws-security зависимость от версии 2.2.7 до 2.7.7.

  5. Добавляем следующие зависимости:

    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-core</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-databinding-aegis</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.cxf</groupId>
        <artifactId>cxf-rt-management</artifactId>
        <version>2.7.7</version>
    </dependency>
    

Опять же, я предполагаю, что есть некоторые внутренние изменения в одной из задействованных структур (CXF? Spring?), Которая обрабатывает это внутренне. Если это предположение верно, то:

  1. Какая часть системы сборки изменяет этот атрибут пространства имен?
  2. Как мне восстановить его прежнее поведение?
  3. Почему клиенты нарушают такие незначительные изменения? (т.е. содержание ответа идентично!)

Обновление 1: виновником оказалось изменение версии пакетов org.apache.cxf с 2.2.7 на 2.7.7.

Похоже, что новее не всегда лучше... разве есть способ программно заставить устаревшее поведение удалять префиксы пространства имен?

Обновление 2: Использование CXF 2.2.7 на Tomcat7 / JRE7 имело побочный эффект при уничтожении сервера Tomcat после отправки одного сообщения SOAP (похоже, связано с SSL).

Тот факт, что почтенный сервер, такой как Tomcat, может умереть из-за одного мошеннического пакета.war, вызывает серьезное беспокойство, но поскольку я не могу исправить Tomcat и не нашел программного способа обойти проблему неявного префикса пространства имен, я пробовал различные стабильные выпуски CXF, которые будет демонстрировать устаревшее поведение, не убивая Tomcat.

Я пробовал версии 2.7.1 и 2.6.10, но в конце концов только 2.5.9 работал.

Я надеюсь, что это помогает кому-то, кто сталкивается с подобной проблемой.

1 ответ

Решение

Соответствующая реализация XML не может умереть из-за изменений в использовании атрибутов xmlns. Выражение одной и той же модели данных с префиксом или без, это одно и то же. Если ваш клиент потерпел неудачу, вам нужно исправить клиента. Если у вас есть клиенты, которые чувствительны к использованию префиксов пространства имен вместо реальной модели данных, CXF не обязательно является хорошим выбором.

Скорее всего, CXF обновился до более новой версии JAX-B, и он передумал насчет префиксов пространства имен.

Чтобы уточнить это: Apache CXF был разработан, чтобы сосредоточиться на стандартных веб-сервисах. Apache Axis традиционно заполняет пространство для нестандартных веб-сервисов. Так что нет, сообщество разработчиков CXF никогда не беспокоилось о "стабильности префиксов". Если XML является формально правильным, тесты CXF счастливы.

По этой и многим другим причинам CXF делегирует генерацию XML для веб-сервисов JAX-B официальной эталонной реализации JAX-B. Новые версии CXF подхватывают новые версии JAX-B. JAX-B время от времени вносит изменения, которые приводят к перестановке префиксов пространства имен.

Генерация XML в CXF является подключаемой, поэтому, если вы хотите использовать более старый JAX-B или свернуть свой собственный, вы можете. Вы можете предоставить "Поставщика" и выполнить всю работу самостоятельно, если хотите.

В CXF есть опция для передачи объекта в JAX-B, который решает, какой префикс использовать для какого пространства имен, но я не думаю, что его можно использовать для принудительной дефолта определенного пространства имен. Возможно, вы сможете получить то, что вы хотите, с провайдером и тщательно настроенным вызовом JAX-B API.

Архив списка рассылки CXF User содержит сотни сообщений от людей, которые идут вверх по течению с префиксами пространства имен.

(Что касается смерти кота, ну, это другой вопрос.)

Другие вопросы по тегам