這個問題讓我陷入了近兩天的困境,我真的需要一些幫助來解決它。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:
ReportsControllerService和MonitoringControllerService擴展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,所以我可以重構,但我想明白爲什麼這種方式不工作。
你的問題有點不清楚:你打電話給服務?你是否控制了服務和客戶? – kolossus
@kolossus,我編輯了我的問題來回答你的問題。 – rorschach
什麼是'ReportsControllerService'和'getReportsControllerPort()'中發生了什麼? – kolossus