Вам необходимо отредактировать UserGroup.wsdl вручную перед созданием заглушек.Вам необходимо добавить processContents='skip'
к тегу <s:any>
, в котором определен ответ.
<s:element name="GetUserCollectionFromGroupResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetUserCollectionFromGroupResult">
<s:complexType mixed="true">
<s:sequence>
<!-- Added the "processContents" attribute below -->
<s:any processContents='skip' />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
Затем при обработке ответа JAXB вернет дочерние элементы в качестве элементов DOM:
UserGroup service = new UserGroup();
UserGroupSoap port = service.getUserGroupSoap();
GetUserCollectionFromGroupResult usersCollection = port.getUserCollectionFromGroup(Settings.usersGroup);
List<Object> content = usersCollection.getContent();
org.w3c.dom.Element usersElement = (org.w3c.dom.Element) content.get(0);
Почему это работает
Проблема вызвана сочетанием условий:
A.Ответ, возвращаемый веб-службой, содержит тег <GetUserCollectionFromGroup>
:
<GetUserCollectionFromGroupResult>
<GetUserCollectionFromGroup>
<Users>
<User ID="4" Name="User1_Display_Name" />
<User ID="5" Name="User2_Display_Name" />
</Users>
</GetUserCollectionFromGroup>
</GetUserCollectionFromGroupResult>
B.Схема, встроенная в WSDL, определяет <GetUserCollectionFromGroup>
как содержащий один дочерний элемент, <groupName>
(это элемент, используемый для выполнения запроса):
<s:element name="GetUserCollectionFromGroup">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="groupName" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
C.JAXB учитывает атрибут processContents
<xs:any>
(см. Отображение).Когда processContents='strict'
, JAXB пытается сопоставить (и маршаллизировать) дочерние элементы на основе пространства имен, к которому они принадлежат.
D.Определение схемы WSDL для <GetUserCollectionFromGroupResult>
включает <xs:any>
:
<s:element name="GetUserCollectionFromGroupResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="GetUserCollectionFromGroupResult">
<s:complexType mixed="true">
<s:sequence>
<s:any/>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
E.Если processContents
опущено, по умолчанию используется значение strict
.
. Таким образом, когда JAX-WS / JAXB обрабатывает результаты веб-службы, он пытается маршалировать дочерние элементы <GetUserCollectionFromGroupResult>
, используя схему.Дочерние элементы отображаются в ответе как принадлежащие к тому же пространству имен, что и запрос.Когда элемент <GetUserCollectionFromGroup>
обрабатывается, он направляется в экземпляр того же класса, который использовался в запросе для элемента <GetUserCollectionFromGroup>
.Таким образом, вы фактически заблокированы от получения элементов <Users>
.
Я искал максимумы и минимумы, и единственное решение (я), которое я могу найти, - это эфир (а) отредактировать WSDL какописано в начале этого ответа, или (б) редактировать сгенерированные заглушки.Не идеально, но неизбежно в этом случае.
Дополнительную информацию об элементе схемы <xs:any>
(и атрибуте processContents
) можно найти в MSDN здесь .