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

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

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

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

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

Я что-то принципиальное не упустил?!?

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

Джефф


person Jeff Morin    schedule 13.10.2011    source источник
comment
Есть несколько аннотаций @SchemaValidation. У меня работает com.sun.xml.ws.developer.SchemaValidation. Я изначально по ошибке использовал com.sun.xml.internal.ws.developer.SchemaValidation и не работал.   -  person Gonzalo Garcia Lasurtegui    schedule 14.10.2011


Ответы (2)


Я наконец нашел в чем дело ...

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

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

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

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

Спасибо,

Джефф

person Jeff Morin    schedule 14.10.2011

О брат!...

Чтобы переопределить 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.

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

Джефф

person Jeff Morin    schedule 14.10.2011