#java #jax-ws #rpc #xml-namespaces
#java #jax-ws #rpc #xml-пространства имен
Вопрос:
Наличие игрушечного сервиса, как показано ниже
@WebService(targetNamespace="http://www.example.org/stock")
@SOAPBinding(style=Style.RPC,parameterStyle=ParameterStyle.WRAPPED)
public class GetStockPrice {
@WebMethod(operationName="GetStockPrice",action="urn:GetStockPrice")
@WebResult(partName="Price")
public Double getPrice(
@WebParam(name="StockName")
String stock
) {
return null;
}
}
Сгенерированный JAX-WS клиент создает сообщение SOAP, в котором параметр StockName не имеет пространства имен:
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:GetStockPrice xmlns:ns2="http://www.example.org/stock">
<StockName>IBM</StockName>
</ns2:GetStockPrice>
</S:Body>
</S:Envelope>
Я бы ожидал и хотел, чтобы StockName был сгенерирован как
<ns2:StockName>IBM</ns2:StockName>
т.е. в целевом пространстве имен, а не в анонимном (ns2 не используется по умолчанию, насколько я могу видеть из сообщения).
Интересно, как заставить JAX-WS добавлять целевое пространство имен к вложенным элементам сообщения?
Попытка указать пространство имен в аннотации WebParam ничего не изменила, поскольку этот параметр игнорируется при использовании RPC.
Или… Означает ли это, что параметры в стиле RPC всегда анонимны?
Обновить
Какой я глупый. Частично решена. Что мне нужно было сделать, так это
- style=Document, чтобы включить целевые пространства имен для элементов
- параметр style=Wrapped, чтобы включить элемент верхнего уровня
- укажите целевое пространство имен для WebParam (почему service one не используется? в документации говорится, что следует использовать пространство имен service)
Это:
@WebService(targetNamespace="http://www.example.org/stock")
@SOAPBinding(style=Style.DOCUMENT,parameterStyle=ParameterStyle.WRAPPED)
public class GetStockPrice {
@WebMethod(operationName="GetStockPrice",action="urn:GetStockPrice")
@WebResult(partName="Price")
public Double getPrice(
@WebParam(name="StockName",targetNamespace="http://www.example.org/stock")
String stock
) {
return null;
}
}
Тем не менее, клиент по-прежнему ожидает возвращаемое значение без какого-либо пространства имен, даже если я попытаюсь объявить его предоставление. Это сбивает с толку.
Комментарии:
1. Я сходил с ума здесь на прошлой неделе, потому что не мог понять, почему у дочерних элементов нет пространства имен. Большое спасибо, чувак!
Ответ №1:
Такое поведение соответствует профилю WSI-Basic. Если вы посмотрите на:
http://www.ws-i.org/profiles/basicprofile-1.1.html#Part_Accessors
в разделе 4.7.20, утверждение R2735 конкретно указано, что для RPC / Literal элементы доступа к части должны быть помещены в элементы без пространства имен.
Комментарии:
1. Это интересный ответ / справочный документ, но, насколько я понимаю, он применим только к RPC / литералу, а не к Документу / литералу, который, как ожидается, будет иметь правильное пространство имен и префиксы. В спецификации WSDL есть пример запроса SOAP, который включает префикс дочернего пространства имен: w3.org/TR/wsdl#_Toc492291097 JAX-WS, похоже, поддерживает / включает надлежащие пространства имен XML даже в режиме «Документ» — есть ли еще одна спецификация, которую я упускаю?
2. «elementFormDefault» Это чрезвычайно важно для просмотра WSDL, чтобы увидеть, определяют ли они, имеет ли
<StockName>IBM</StockName>
префикс пространства имен или нет.
Ответ №2:
У меня тоже такая же проблема. я разработал клиент веб-сервиса, используя JAX-WS, с имитацией пользовательского интерфейса SOAP.Мой клиент веб-сервиса работает нормально. но когда я тестирую с реальным сервером (веб-служба axis). Я получил нулевые значения.
Ответ моделирования пользовательского интерфейса SOUP, подобный этому
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.aml.infrasofttech.biz" xmlns:dat="http://dataobject.aml.infrasofttech.biz">
<soapenv:Header/>
<soapenv:Body>
<web:getCIPMatchResponse>
<!--1 or more repetitions:-->
<web:getCIPMatchReturn>
<dat:countries>?</dat:countries>
<dat:dob>?</dat:dob>
<dat:fullName>?</dat:fullName>
<dat:isError>?</dat:isError>
<dat:listName>?</dat:listName>
<dat:passport>?</dat:passport>
<dat:percentage>?</dat:percentage>
<dat:sdnId>?</dat:sdnId>
<dat:sdnName>?</dat:sdnName>
</web:getCIPMatchReturn>
</web:getCIPMatchResponse>
</soapenv:Body>
</soapenv:Envelope>
Но на сервере он отвечает с таким пространством имен, как это..
<countries>?</countries>
<dob>?</dob>
<fullName>?</fullName>
<isError>?</isError>
<listName>?</listName>
<passport>?</passport>
<percentage>?</percentage>
<sdnId>?</sdnId>
<sdnName>?</sdnName>
Сгенерированный JAX-WS код выглядит следующим образом.
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SdnBean", namespace = "http://dataobject.aml.infrasofttech.biz", propOrder = {
"countries",
"dob",
"fullName",
"isError",
"listName",
"passport",
"percentage",
"sdnId",
"sdnName"
})
public class SdnBean {
Затем я должен изменить клиентский jax-ws код @XMLType, как показано ниже
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"countries",
"dob",
"fullName",
"isError",
"listName",
"passport",
"percentage",
"sdnId",
"sdnName"
})
public class SdnBean {
Теперь это свяжет ответ soap без пространства имен.