Преамбула
Существует давно известная проблема совместимости 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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> | |
<soap:Body> | |
<ns2:getObjectGroupResponse xmlns:ns2="http://example.ru/WebService"> | |
<return> | |
<guid>E25534B1A6DA7E95E040007F02001857</guid> | |
<hash>5388E4E31975F9561916A34FC3BB6243</hash> | |
<id>19483</id> | |
<typeId>4</typeId> | |
</return> | |
</ns2:getObjectGroupResponse> | |
</soap:Body> | |
</soap:Envelope> |
а вложенные объекты как видно без неймспейса.
Вот определение элемента <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.This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
<lib:library xmlns:lib="http://dyomedea.com/ns/library"> <book id="b0836217462" available="yes"> <isbn> 0836217462 </isbn> <title> Being a Dog Is a Full-Time Job </title> </book> </lib:library>
Как утверждается, это вполне законный способ представления сущности.
Следйющий пример из [2] характерен для 1С.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<library xmlns="http://dyomedea.com/ns/library"> | |
<book id="b0836217462" available="yes"> | |
<isbn> | |
0836217462 | |
</isbn> | |
<title> | |
Being a Dog Is a Full-Time Job | |
</title> | |
</book> | |
</library> |
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")
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<xs:element name="getObjectGroup" type="tns:getObjectGroup"/> | |
<xs:element name="getObjectGroupResponse" type="tns:getObjectGroupResponse"/> | |
<xs:complexType name="getObjectGroup"> | |
<xs:sequence> | |
<xs:element name="type" type="xs:int"/> | |
</xs:sequence> | |
</xs:complexType> |
элемент <xs:element name="type" type="xs:int"/> не принадлежит tns, он принадлежит xs (xmlns:xs="http://www.w3.org/2001/XMLSchema").
Однако 1C при этом формирует пакет следующего вида:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> | |
<soap:Header/> | |
<soap:Body> | |
<ns2:getObjectGroup xsi:type="getObjectGroup" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://mycompany.ru/MyCompanySyncWebService"> | |
<ns2:type>1</ns2:type> | |
</ns2:getObjectGroup> | |
</soap:Body> | |
</soap:Envelope> |
Решение
Перевести JAX-WS в режим elementFormDefault="qualified" без ручного указания неймспейсов, чтобы сервис работал в стиле 1C.В пакете веб-сервиса, допустим это "ru.company.ws", создать файл package-info.java
следующего содержания:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@javax.xml.bind.annotation.XmlSchema( | |
namespace = "http://exchange.services/", | |
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED | |
) | |
package ru.company.ws; |
тогда WSDL приобрет вид :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<wsdl:definitions name="WebServiceWS" targetNamespace="http://exchange.services/"> | |
<wsdl:types> | |
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://exchange.services/"> | |
... |
Теперь сервис будет производить ответ следующего вида:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> | |
<soap:Body> | |
<downloadResponse xmlns="http://exchange.services/"> | |
<return> | |
... | |
</return> | |
</getObjectGroupResponse> | |
</soap:Body> | |
</soap:Envelope> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> | |
<soap:Body> | |
<getOUListResponse xmlns="http://mycompany.ru/MyCompanySyncWebService"> | |
<return> | |
<id>1001</id> | |
... | |
</return> | |
</getOUListResponse> | |
</soap:Body> | |
</soap:Envelope> |
Источники
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