JAX-WS RI не применяет ограничения XSD

#validation #xsd #jax-ws #restriction

#проверка #xsd #jax-ws #ограничение

Вопрос:

В настоящее время я разрабатываю несколько веб-сервисов, используя эталонную реализацию 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. Даже отрицательные значения считаются допустимыми, несмотря на xsd:positiveInteger тип!
  • О нарушениях ограничений длины строки (например, lastName длина более 25 символов) также не сообщается.

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

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

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

Я упускаю что-то фундаментальное здесь ?!?

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

Джефф

Комментарии:

1. Существует несколько аннотаций @SchemaValidation. Тот, который работает для меня, — это com.sun.xml.ws.developer. Проверка схемы. Я использовал com.sun.xml.internal.ws.developer. Проверка схемы в первую очередь произошла по ошибке и не сработала.

Ответ №1:

Я наконец нашел, что не так…

Чтобы заставить мои веб-службы работать в контексте 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 ), раздел дополнительных заметок, я вернул wsdlLocation атрибут, и теперь все ограничения соблюдаются должным образом.

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

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

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

Спасибо,

Джефф

Ответ №2:

О, брат !…

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

После выполнения множества тестов я выяснил, что наличие @WebService класса с аннотацией, расширяющего реализацию моей веб-службы, не позволяет проверке 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 , все снова будет работать правильно, за исключением модульных тестов, конечно.

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

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

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

Джефф