среда, 21 октября 2015 г.

О совместимости веб-сервисов JAX-WS и 1С


Преамбула

Существует давно известная проблема совместимости 1С с веб-сервисами на Java и не только.
После обзора материалов в интернете по практике использования веб-сервисов на платформе Java Enterprise Edition (JAX-WS) из платформы 1С к сожалению пришлось признать, что ни одной успешной попытки не зафиксировано.

Вот два показательных примера:
http://www.sql.ru/forum/1038337/web-servis-java-1s-klient-problema-peredachi-strokovogo-parametra
http://www.forum.mista.ru/topic.php?id=538212

Через два дня я сообразил в чем собственно проблема.

Суть проблемы.

В определении типов указывается явное определение пространств имен по умолчанию:

xs:schema:attributeFormDefault="unqualified"
xs:schema:elementFormDefault="qualified"


Суть проблемы заключается в том что 1С при разборе WSDL, в частности схемы данных, не обращает внимания на атрибут elementFormatDefault. Она полагает что его значение всегда равно "qualified".


По умолчанию все элементы тела SOAP-пакета имеют form="unqualified".
Это позволяет клиентам читать вложенные элементы без явного указания их неймспейса.

Вот например ответа сервиса на запрос getObjectGroup в режиме Document/Literal без явного указания неймспейсов для атрибутов сущности Object:

Как видно, неймспейс выходного документа метода getObjectGroupResponse равен http://example.ru/WebService, что является действием атрибута targetNamespace -- см. [1],
а вложенные объекты как видно без неймспейса.


Вот определение элемента <xsd:element> из книги "Справочник по XML-схемам (XSD)" с сайта MSDN [2].

 form
    Форма для элемента . Значением по умолчанию является значение атрибута elementFormDefault элемента schema, содержащего этот атрибут. Значение должно быть одной из следующих строк: «qualified» или «unqualified».
    Если значение не квалифицировано, элемент не обязательно квалифицировать с помощью префикса пространства имен.
    Если значение квалифицировано, элемент нужно квалифицировать с помощью префикса пространства имен.
    Необязательный.

А вот пример из книги [3]

These attributes both have default values of their own, which are: elementFormDefault="unqualified" and attributeFormDefault="unqualified". These values are appropriate to the case in which only the document element uses a namespace:
Since global elements and attributes must be qualified, defining this schema as a single schema requires that all the elements and attributes are locally defined.

Как утверждается, это вполне законный способ представления сущности.

Следйющий пример из [2] характерен для 1С.


Another combination, elementFormDefault="qualified" and attributeFormDefault="unqualified" matches the common case in which a namespace is attached to the root element as the default namespace that will, by definition apply to the included elements but not to the attributes. (Per the Namespaces Recommendation, the default namespace does not apply to attributes.)




Значит 1С исходит из предположения, что в XML-схеме интерфейса xs:elementFormDefault равен "qualified",
что не соответствует действительности.

Эксперимент с ручной модификацией WSDL-ки показал, что 1С-ка безразлична к параметру xs:element:form=qualified/unqualified.
следовательно реализация парсера 1С не поддерживает спецификацию XMLSchema полностью.


Симметричная проблема возникает и при разборе пакетов, сформированными 1С.
Пример из WSDL:
getObjectGroup принадлежит tns (targetNamespace="http://mycompany.ru/MyCompanySyncWebService")

Как видно,
элемент <xs:element name="type" type="xs:int"/> не принадлежит tns, он принадлежит xs (xmlns:xs="http://www.w3.org/2001/XMLSchema").
Однако 1C при этом формирует пакет следующего вида:

Что не соответствует XML-схеме и явно является багом.

Решение

Перевести JAX-WS в режим elementFormDefault="qualified" без ручного указания неймспейсов, чтобы сервис работал в стиле 1C.


В пакете веб-сервиса, допустим это "ru.company.ws", создать файл package-info.java
следующего содержания:


тогда WSDL приобрет вид :

Как видно, elementFormDefault стал равен "qualified".

Теперь сервис будет производить ответ следующего вида:

Такой вариант работы с неймспейсами на ура воспринимается 1С, ответ приходит в виде в каком 1с-ка его и рассчитывает увидеть :


Источники

1. Задание целевого пространства имен с помощью атрибута targetNamespace /
    http://msdn.microsoft.com/ru-ru/library/ms172720.aspx

2. Справочник по XML-схемам (XSD) /
   http://msdn.microsoft.com/ru-ru/library/ms256118%28v=vs.110%29.aspx

3. Xml Schema, Eric van der Vlist, глава 10.3 (To Qualify Or Not to Qualify?) /
   http://docstore.mik.ua/orelly/xml/schema/ch10_03.htm

4. http://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=1038337&msg=16612010



log4js. how to set default logging levels for channels