JAX-WS RI не применяет ограничения XSD - PullRequest
3 голосов
/ 13 октября 2011

В настоящее время я разрабатываю несколько Web-сервисов, используя эталонную реализацию JAX-WS (версия 2.1.7).Они основаны на контрактах, то есть файлы WSDL и XSD не генерируются wsgen.

Это позволяет мне свободно использовать ограничения XSD для усиления проверки значений, передаваемых моим службам через сообщения SOAP.Вот два примера таких «ограниченных» элементов XSD:

<xsd:element name="maxResults" minOccurs="1">
  <xsd:simpleType>
    <xsd:restriction base="xsd:positiveInteger">
      <xsd:minInclusive value="1"/>
      <xsd:maxInclusive value="1000"/>
    </xsd:restriction>
  </xsd:simpleType>
</xsd:element>
<xsd:element name="lastName" minOccurs="0">
  <xsd:simpleType>
    <xsd:restriction base="xsd:string">
      <xsd:minLength value="1"/>
      <xsd:maxLength value="25"/>
    </xsd:restriction>
  </xsd:simpleType>
</xsd:element>

Я добавил аннотацию @SchemaValidation к своим классам обслуживания, чтобы обеспечить проверку схемы.Однако JAX-WS не обеспечивает соблюдение правил проверки, как ожидалось.Поведение выглядит следующим образом:

  • Пропущенные обязательные элементы сообщаются правильно (например, пропускаются maxResults).
  • Неверные значения (например, символьные данные в целочисленном поле) являются правильнымитакже сообщается.
  • Нарушения ограничения интервала (например, maxResults> 1000 или maxResults <1) проходят через процесс проверки без сообщения и внедряются в мои Java-структуры, сгенерированные JAXB.Даже отрицательные значения считаются действительными, несмотря на тип <code>xsd:positiveInteger!
  • Нарушения ограничения длины строки (например, lastName длина более 25 символов) также не сообщаются.

В другихслова, ограничения, которые появляются в тегах <xsd:element>, соблюдаются правильно, но элементы <xsd:restriction>, по-видимому, полностью игнорируются JAXB при использовании в контексте на основе JAX-WS.

Я написал тестовый класс для проверки своегоОграничения XSD при использовании голого JAXB (без JAX-WS).В результате все ограничения соблюдаются правильно.

Это дает мне ощущение, что может быть ошибка в использовании JAXB JAX-WS ... если, конечно, я что-то делаю неправильно, конечно...

Я что-то упустил здесь?!?

Заранее благодарен за любую помощь,

Джефф

Ответы [ 2 ]

2 голосов
/ 14 октября 2011

Я наконец-то обнаружил, что не так ...

Для того, чтобы мои Web-сервисы работали в контексте JUnit, т.е. опубликованы через Endpoint.publish(), мне пришлось удалить атрибут wsdlLocation из моего @WebService аннотаций.В противном случае wsdlLocation = "WEB-INF/wsdl/SearchIndividualsV1_0.wsdl", переданный аннотации @WebService, конфликтует со значением URL, переданным методу Endpoint.publish(), http://127.0.0.1:9000/rpe-ws/SearchIndividuals.

После прочтения блога Глена Маззы (http://www.jroller.com/gmazza/entry/soap_xml_schema_validation), Дополнительные примечания * В разделе 1015 * я вернул атрибут wsdlLocation, и теперь все ограничения теперь правильно соблюдаются.

Другими словами, удаление wsdlLocation в аннотации @WebService делаетне мешает работе самой службы, но предотвращает принудительное применение ограничений, объявленных в элементах <xsd:restrictions>. Ограничения, объявленные в элементах <xsd:element>, однако, все еще применяются правильно.

Поэтому я возвращаюсь крешить эту проблему совместимости wsdlLocation, чтобы мои модульные тесты работали правильно, но это гораздо менее важно, чем нерабочие проверки в производственном контексте ...

На всякий случай ... У кого-то есть идеяоб этой несовместимости расположения WSDL при запуске веб-службы в не-веб-контексте?

Спасибо,

Джефф

0 голосов
/ 14 октября 2011

О, брат! ...

Чтобы переопределить wsdlLocation для моих тестов JUnit, я создал производные от моих реализаций Web-сервиса, которые переопределяют только аннотацию @WebService.В результате я столкнулся с той же проблемой, которую окончательно решил сегодня утром (см. Мой первый ответ выше).

Проведя множество тестов, я выяснил, что это присутствие @WebService -аннотированногокласс, расширяющий мою реализацию Web-сервиса, которая не позволяет валидации XSD правильно обрабатывать <xsd:restriction> теги.

Чтобы проиллюстрировать это странное поведение, предположим, что у меня есть следующие классы:

@WebService(...)
public interface JeffWebService {...}

@WebService(..., wsdlLocation = "path/myWsdl.wsdl", ...)
public class JeffWebServiceImpl implements JeffWebService {...}

где path/myWsdl.wsdl правильно находит WSDL.Тогда проверка XSD работает правильно, т.е. содержание моего первого ответа выше полностью допустимо.

Теперь я добавляю следующий класс, который я использую в моих вызовах Endpoint.publish() на основе JUnit:

@WebService(..., wsdlLocation = "alternatePath/myWsdl.wsdl", ...)
public class TestWebServiceImpl extends JeffWebServiceImpl {}

, которая переопределяет только аннотацию @WebService.Затем проверка XSD исключает теги <xsd:restriction>, как это делалось до указания атрибута wsdlLocation, несмотря на тот факт, что я все еще использую реализацию JeffWebServiceImpl в своем коде, не являющемся JUnit!Если я закомментирую аннотацию в TestWebServiceImpl, то все снова будет работать правильно, за исключением, конечно, модульных тестов.

Другими словами, как только в classpath появится какой-то класс, расширяющий мою реализацию Web-сервиса.аннотация @WebService наиболее определенного класса переопределяет все остальные, независимо от того, какой класс я использую в обычном контексте веб-приложения.Странно, не правда ли?!?

Итог: я пока отключу юнит-тесты на основе Endpoint.Если я (или кто-то читает эту ветку) найду чистый, не фиктивный способ интеграции как производственных, так и JUnit-конфигураций, я рассмотрю вопрос о том, чтобы вернуть их в свой набор тестов JUnit.

Надеюсь, эта ветка поможет всемстолкнуться с той же проблемой, решить ее быстрее, чем я ...

Джефф

...