#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.
Я надеюсь, что этот поток поможет любому, кто столкнется с такой же проблемой, решить ее быстрее, чем я…
Джефф