JAX-WS: почему вложенные элементы находятся в пространстве имен «»?

#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 без пространства имен.