2012-04-16 1 views
12

Я работаю с WSDL-файлом клиента, который использует те же определения элемента для входных и выходных сообщений, но у меня возникают проблемы с получением JAX-WS/JAXB, чтобы отменить ответ.jax-ws/wsimport создает WebMethod с возвратом void - тот же Request/ResponseWrapper

<wsdl:message name="invokeServiceRequest"> 
    <wsdl:part element="impl:requests" name="multiRequestWrapper"/> 
</wsdl:message> 
<wsdl:message name="invokeServiceResponse"> 
    <wsdl:part element="impl:requests" name="result"/> 
</wsdl:message> 
<wsdl:portType name="GCGatewayPortType"> 
    <wsdl:operation name="requests"> 
     <wsdl:input message="impl:invokeServiceRequest" name="invokeServiceRequest"/> 
     <wsdl:output message="impl:invokeServiceResponse" name="invokeServiceResponse"/> 
    </wsdl:operation> 
</wsdl:portType> 

По какой-то причине код, генерируемый wsimport имеет возврат пустот, а INOUT PARAMS, кажется, не обновляется, когда будет получен ответ.

/** 
* This class was generated by the JAX-WS RI. 
* JAX-WS RI 2.1.7-b01- 
* Generated source version: 2.1 
*/ 
... 
@WebMethod 
@RequestWrapper(localName = "requests", targetNamespace = "http://cg.test.com/", className = "com.test.cg.RequestsType") 
@ResponseWrapper(localName = "requests", targetNamespace = "http://cg.test.com/", className = "com.test.cg.RequestsType") 
public void requests(
    @WebParam(name = "paramOne", targetNamespace = "http://cg.test.com/", mode = WebParam.Mode.INOUT) 
    Holder<String> paramOne, 
    @WebParam(name = "paramTwo", targetNamespace = "http://cg.test.com/", mode = WebParam.Mode.INOUT) 
    Holder<String> paramTwo, 
    @WebParam(name = "requestList", targetNamespace = "http://cg.test.com/", mode = WebParam.Mode.INOUT) 
    Holder<List<RequestType>> requestList); 

Когда я называю port.request(paramOne, paramTwo, requestList), я могу видеть, что запрос SOAP отправляется на сервер, который отвечает соответствующий ответ SOAP:

<soapenv:Envelope ...> 
    <soapenv:Header /> 
    <soapenv:Body> 
     <requests ...> 
      <paramOne>1</paramOne> 
      <paramTwo>2</paramTwo> 
      <requestList> 
       <!-- various elements that JAXB has generated code for --> 

Однако, когда я бегу мое приложение в режиме отладки , Я вижу каждый экземпляр RequestType в представлении переменных отладчика, но потому, что RequestsType имеет <xsd:choice> с RequestData или ResponseData, последний имеет значение null, а RequestData - как я уже говорил.

Я успешно использовал JAX-WS для других проектов, но в этих случаях он сгенерировал код с @WebResult и не-void возвращаемым типом, названным в честь WebResult. В этом проекте я думаю, что я не получаю WebResult, потому что JAX-WS решил, что типы запросов и ответов одинаковы, и он может повторно использовать один и тот же объект, но как я могу заставить его обновить этот объект с данными из ответ?

+0

Не могли бы вы разместить свой документ WSDL? – Phani

ответ

10

У меня была такая же проблема. Я экспериментировал с именами, которые я использовал для различных типов, элементов, имен сообщений, имен операций и т. Д. Я, наконец, нашел ключ, и то, что вы сказали в своем вопросе на самом деле у меня близко к ответу:

В этом проекте, я думаю, что я не получаю WebResult потому что JAX-WS решил, что запрос и типы ответов одинаковы, и он может повторно использовать один и тот же объект - но как мне его получить, чтобы обновить этот объект с данными из ответа?

Я посмотрел на свой wsdl, который генерировал аналогичный Java-код (с возвратом void и списком параметров вместо одного параметра объекта). Но у меня разные типы ввода и вывода. Как насчет моего wsdl был похож на ваш?

Название операции было таким же, как имя элемента, определенного для типа ввода. Я бы предположил, что вы меняете свое имя операции из «запросов» на нечто вроде «processRequests» или оставляете только имя операции и изменяете имя элемента, используемого для определений сообщений.

<wsdl:operation name="requests"> 

становится

<wsdl:operation name="processRequests"> 

Я хотел бы услышать, если это работает для вас.

+0

Извините, я перешел в другую компанию и больше не имею доступа к коду для этого проекта.Если бы я контролировал схему WSDL, я бы изменил корневой элемент ответа от «запросов» на «ответ» –

+0

Привет! Я сталкиваюсь с той же ошибкой. Изменение имени операции работает. Zach, вы знаете, является ли это ограничением wsimport или есть способ разрешить wsimport обрабатывать случаи, когда имя операции совпадает с именем типа параметра запроса? – Arci

+0

@Arci Я не уверен в этом. Если изменение имени операции не является решением, с которым вы действительно можете перейти (возможно, wsdl находится вне вашего контроля), то, возможно, стоит создать классы с помощью другого инструмента, такого как Axis. – ZachOfAllTrades

11

Вы можете решить эту проблему, поручив JAX-WS отключить упаковку. Это делается через файл привязок JAX-WS.

<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"> 
    <jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle> 
</jaxws:bindings> 
+2

Это правильный ответ, выдержка. Просто примечание: вы сохраняете код выше в файле * .xjb и инструктируете wsimport использовать его так: «wsimport -b disable-wrappings.xjb your.wsdl» – Aramir

+1

Правильный ответ, потраченный впустую некоторое время, пока я не попал сюда .. .... – AntJavaDev

+0

Исаак и @ Арамир Я расплакался от радости, когда нашел ваш ответ. Огромное спасибо. – cristianoms