2015-05-06 64 views
6

這個問題讓我陷入了近兩天的困境,我真的需要一些幫助來解決它。SOAP服務響應無法映射

我已經使用wsimport從兩個不同的.wsdl文件爲Java項目生成代碼。

第一個服務工作正常,但由於某種原因,第二個服務的響應無法解組到響應對象。

工作業務:

@WebMethod(action = "[actionName]") 
@WebResult(name = "getSimpleCompanyInfoResponse", partName = "getSimpleCompanyInfoResponse") 
public GetSimpleCompanyInfoResponse getSimpleCompanyInfo(
     @WebParam(name = "getSimpleCompanyInfoRequest", partName = "getSimpleCompanyInfoRequest") GetSimpleCompanyInfoRequest getSimpleCompanyInfoRequest); 

響應POJO:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "getSimpleCompanyInfoResponse", propOrder = { 
    //variables 
}) 
public class GetSimpleCompanyInfoResponse { 
    //variables 
} 

響應XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="[namespaceUri]" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <SOAP-ENV:Body> 
     <ns1:getSimpleCompanyInfoResponse> 
      <getSimpleCompanyInfoResponse> 
       //variables 
      </getSimpleCompanyInfoResponse> 
     </ns1:getSimpleCompanyInfoResponse> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

工作服務:

@WebMethod(operationName = "PersonnelInfo", action = "[actionName]") 
@WebResult(name = "PersonnelInfoResponse", partName = "PersonnelInfoResponse") 
public PersonnelInfoResponse personnelInfo(
@WebParam(name = "PersonnelInfoRequest", partName = "PersonnelInfoRequest") PersonnelInfoRequest personnelInfoRequest); 

響應POJO:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "PersonnelInfoResponse", propOrder = { 
    //variables 
}) 
public class PersonnelInfoResponse { 
    //variables 
} 

響應XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="[namespaceUri]" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <SOAP-ENV:Body> 
     <ns1:PersonnelInfoResponse> 
      //variables 
     </ns1:PersonnelInfoResponse> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

使用-Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump =真或使用Wireshark進行監控我可以看到來自第二個服務的響應信封通過恰好的罰款和解組不會拋出任何例外,但最終PersonnelInfoResponse爲空。

我能看到的唯一區別是XML中的第二個服務響應負載缺少似乎是問題的外部元素。但是,我不知道如何「修復」它,因此它不尋找外部元素。

如果有什麼不清楚或缺失,請讓我知道,我會盡力給你所有的信息。

編輯:

不,我很遺憾沒有對服務本身的任何控制,我只有和的.wsdl的.xsd。

我打電話的服務這樣的:

ReportsControllerPortType port = new ReportsControllerService().getReportsControllerPort(); 

PersonnelInfoRequest request = new PersonnelInfoRequest(); 
//fill the required fields in the request, username, password, etc. 

PersonnelInfoResponse response = port.personnelInfo(request); 

客戶端側的服務存根(ReportsControllerService & ReportsControllerPortType)也由的wsimport根據的.wsdl和的.xsd自動生成。

編輯2:

刪除操作名稱不工作,服務無法初始化。以下是兩者的定義。WSDL-S:

工作業務:

<wsdl:message name="getSimpleCompanyInfoRequest"> 
    <wsdl:part name="getSimpleCompanyInfoRequest" type="tns:getSimpleCompanyInfoRequest" /> 
</wsdl:message> 
<wsdl:message name="getSimpleCompanyInfoResponse"> 
    <wsdl:part name="getSimpleCompanyInfoResponse" type="tns:getSimpleCompanyInfoResponse" /> 
</wsdl:message> 

<wsdl:portType name="MonitoringControllerPortType"> 
    <wsdl:operation name="getSimpleCompanyInfo"> 
     <wsdl:input message="tns:getSimpleCompanyInfoRequest" /> 
     <wsdl:output message="tns:getSimpleCompanyInfoResponse" /> 
    </wsdl:operation> 
</wsdl:portType> 

<wsdl:binding name="MonitoringControllerBinding" type="tns:MonitoringControllerPortType"> 
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> 

    <wsdl:operation name="getSimpleCompanyInfo"> 
     <soap:operation soapAction="[domain]/#getSimpleCompanyInfo" style="rpc" /> 
     <wsdl:input> 
      <soap:body use="literal" namespace="[namespaceUri]" /> 
     </wsdl:input> 
     <wsdl:output> 
      <soap:body use="literal" namespace="[namespaceUri]" /> 
     </wsdl:output> 
    </wsdl:operation> 
</wsdl:binding> 

<wsdl:service name="MonitoringControllerService"> 
    <wsdl:port name="MonitoringControllerPort" binding="tns:MonitoringControllerBinding"> 
     <soap:address location="[serviceUri]" /> 
    </wsdl:port> 
</wsdl:service> 

工作服務:

<wsdl:message name="PersonnelInfoRequest"> 
    <wsdl:part name="PersonnelInfoRequest" type="tns:PersonnelInfoRequest" /> 
</wsdl:message> 
<wsdl:message name="PersonnelInfoResponse"> 
    <wsdl:part name="PersonnelInfoResponse" type="tns:PersonnelInfoResponse" /> 
</wsdl:message> 

<wsdl:portType name="ReportsControllerPortType"> 
    <wsdl:operation name="PersonnelInfo"> 
     <wsdl:input message="tns:PersonnelInfoRequest" /> 
     <wsdl:output message="tns:PersonnelInfoResponse" /> 
    </wsdl:operation> 
</wsdl:portType> 

<wsdl:binding name="ReportsControllerBinding" type="tns:ReportsControllerPortType"> 
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> 
    <wsdl:operation name="PersonnelInfo"> 
     <soap:operation soapAction="[domain]/#PersonnelInfo" style="rpc" /> 
     <wsdl:input> 
      <soap:body use="literal" namespace="[namespaceUri]" /> 
     </wsdl:input> 
     <wsdl:output> 
      <soap:body use="literal" namespace="[namespaceUri]" /> 
     </wsdl:output> 
    </wsdl:operation> 
</wsdl:binding> 

<wsdl:service name="ReportsControllerService"> 
    <wsdl:port name="ReportsControllerPort" binding="tns:ReportsControllerBinding"> 
     <soap:address location="[serviceUri]" /> 
    </wsdl:port> 
</wsdl:service> 

編輯3:

ReportsControllerServiceMonitoringControllerService擴展javax.xml.ws.Service幷包含使用的.wsdl模式位置和名稱空間的定義。服務類返回端口類型的對象,你可以看到:

/** 
* This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2 
*/ 
@WebServiceClient(name = "ReportsControllerService", targetNamespace = "[namespaceUri]", wsdlLocation = "[wsdlUri]") 
public class ReportsControllerService extends Service { 

    @WebEndpoint(name = "ReportsControllerPort") 
    public ReportsControllerPortType getReportsControllerPort() { 
     return super.getPort(new QName("[namespaceUri]", "ReportsControllerPort"), ReportsControllerPortType.class); 
    } 
} 

ReportsControllerPortType是其中包含了存在於服務的每一個操作終端的方法的接口

/** 
* This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2 
*/ 
@WebService(name = "ReportsControllerPortType", targetNamespace = "[namespaceUri]") 
@SOAPBinding(style = SOAPBinding.Style.RPC) 
@XmlSeeAlso({ObjectFactory.class}) 
public interface ReportsControllerPortType { 

    @WebMethod(operationName = "PersonnelInfo", action = "[actionName]") 
    @WebResult(name = "PersonnelInfoResponse", partName = "PersonnelInfoResponse") 
    public PersonnelInfoResponse personnelInfo(
     @WebParam(name = "PersonnelInfoRequest", partName = "PersonnelInfoRequest") PersonnelInfoRequest personnelInfoRequest); 
    } 
} 

的事情是,所有的這些類是由JAX-WS根據.wsdl模式自動生成的(如您從註釋中看到的那樣)。這個實現抽象出JDK內部的某個地方,我也無法控制它。是的,我可以重構代碼,所以我繞過JAX-WS,但據我瞭解,這應該是一個事實上標準的方式來使用基於.wsdl的SOAP服務。

該項目使用Spring作爲基礎框架,我已經確認這兩個服務將工作時,我使用Spring-WS,所以我可以重構,但我想明白爲什麼這種方式不工作。

+0

你的問題有點不清楚:你打電話給服務?你是否控制了服務和客戶? – kolossus

+0

@kolossus,我編輯了我的問題來回答你的問題。 – rorschach

+0

什麼是'ReportsControllerService'和'getReportsControllerPort()'中發生了什麼? – kolossus

回答

1

我相信我可能已經發現爲什麼你的web服務行爲不當。根據規範,一個RPC web服務必須履行其肥皂以下標準結合(即@SOAPBinding註解你那裏)

  1. RPC一個style:檢查

  2. 一個useLITERAL:檢查

  3. A parameterStyle of WRAPPED:從您給出的描述看,WRAPPED看起來是n在這裏的情況下,看到你收到一個裸體PersonnelInfoResponse(並可能發送一個裸體PersonnelInfoRequest)沒有任何包裝表明該服務本身已被打破。

the JAX-WS spec的摘錄:

RPC風格的使用方式需要使用WRAPPED參數樣式。偏離這是錯誤

+0

'PersonnelInfoRequest'正在發送出'PersonnelInfo'包裹,但是,結果是一個裸體'PersonnelInfoResponse'。從我在Google上也能找到的問題看來確實存在問題。謝謝你確認。唉,我無法控制服務,所以我重構了代碼並使用Spring-WS進行調用。現在它可以工作。 – rorschach

0

還有就是你的2個呼叫之間有一個明顯的區別:

你應該嘗試從你的第二個電話是不存在的第一個工作一個刪除operationName = "PersonnelInfo"

+0

這不起作用,因爲,據我瞭解,如果它缺少,然後JAX-WS嘗試解析方法簽名的操作名稱。由於該方法以小寫* p *開頭,因此失敗。我用.wsdl定義更新了原始文章,因爲您也可以看到它們在結構上幾乎完全相同。 – rorschach