[英]My jax-ws webservice client returns only empty objects
我有一個第三方網絡服務,我使用 wsimport 為其生成一個客戶端。 對 web 服務的每次調用都成功完成,但我返回的響應對象的所有字段都設置為 null。 監控網絡我可以看到,在網絡上,響應消息中的所有 XML 元素都包含值,因此對象中應該包含非空數據。 此外,使用舊軸 1 生成並使用相同數據調用的相同服務的客戶端返回非空響應。 知道發生了什么嗎? (如果它有任何不同,我正在使用 MOXy 的 JAXB 實現)。
更新:我已經能夠縮小范圍。 wsdl 在它自己的命名空間中定義對象,比如http://www.acme.com/ws
。 我從服務中得到的回應是
<?xml version="1.0" encoding="UTF-8"?>
... SOAP envelope ...
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<result>6003</result>
<ndserr/>
<transid>61437594</transid>
<descriptionerr>BLAH.</descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
... SOAP closing tags ...
並被解組為一個非空的OpINFOWLResponse
,它包裹着一個非空的responseINFOWL
對象,所有的字段都設置為空。 只是為了好玩,我嘗試寫幾行來解組上面的代碼片段(在去除 SOAP 開銷之后)
JAXBContext ctx = JAXBContext.newInstance(OpINFOWLResponse.class);
Unmarshaller u = ctx.createUnmarshaller();
OpINFOWLResponse o = (OpINFOWLResponse) u.unmarshal(new StringReader(theSnippetAbove));
ResponseINFOWL w = o.getResponseINFOWL();
我得到了相同的結果。 如果我將上面的 XML 更改為
<?xml version="1.0" encoding="UTF-8"?>
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<ns1:result>6003</ns1:result>
<ns1:ndserr/>
<ns1:transid>61437594</ns1:transid>
<ns1:descriptionerr>BLAH.</ns1:descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
一切正常。 無賴。
更新(再次) :jaxb-RI 和 Moxy 的行為相同。 仍然不知道出了什么問題。
更新(9 月 9 日) :下面關於命名空間限定錯誤的建議很有趣,但我認為 wsimport 可以解決問題。 無論如何,這是我的package-info.java
@XmlSchema(
namespace = "http://www.acme.com/ws",
elementFormDefault = XmlNsForm.QUALIFIED)
package it.sky.guidaTv.service.remote;
import javax.xml.bind.annotation.XmlSchema;
import javax.xml.bind.annotation.XmlNsForm;
這是ResponseINFOWL
類的相關部分
/*
* <p>Java class for responseINFOWL complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="responseINFOWL">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="result" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="descriptionerr" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="transid" type="{http://www.w3.org/2001/XMLSchema}string"/>
* <element name="ndserr" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
* <element name="wallet" type="{http://www.acme.com/ws}t_wallet" minOccurs="0"/>
* </sequence>
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "responseINFOWL", propOrder = {
"result", "descriptionerr", "transid", "ndserr", "wallet" })
public class ResponseINFOWL {
@XmlElement(required = true)
protected String result;
@XmlElement(required = true)
protected String descriptionerr;
@XmlElement(required = true)
protected String transid;
protected String ndserr;
protected TWallet wallet;
// getters, setters and all.
}
我試過在package-info
使用命名空間,但仍然沒有樂趣。
我最近遇到了與您遇到的完全相同的問題,歸結為我正在聯系的服務返回的內容與其 WSDL 宣傳的內容不同。 該服務使用舊版本的 Apache Axis (1.4),其行為與當前的 JAX-WS 實現相沖突。
特別是,實際響應正文內容上的命名空間不是 JAX-WS 的 wsimport 實用程序生成的客戶端代碼所期望的。 例如,實際響應看起來像這樣,serviceResponse 及其所有子項都在命名空間“ http://foo.com ”中:
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<serviceResponse xmlns="http://foo.com">
<messageReturn>
<messageId>12345</messageId>
<status>Ok</status>
</messageReturn>
</serviceResponse>
</soapenv:Body>
</soapenv:Envelope>
與實際返回的內容相反,由 wsimport 生成的客戶端存根期待類似下面的響應,其中 serviceResponse 元素位於命名空間“ http://foo.com ”中,包含的子 messageReturn 元素位於匿名命名空間中。
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<n1:serviceResponse xmlns:n1="http://foo.com">
<messageReturn>
<messageId>12345</messageId>
<status>Ok</status>
</messageReturn>
</n1:serviceResponse>
</soapenv:Body>
</soapenv:Envelope>
由於我無法更改我正在使用的服務,因此我自己編寫了一個新的 WSDL,它使用包裝的 doc-literal 綁定來顯式控制響應(當然還有請求)的預期結構。 IBM Developerworks上有一篇關於 WSDL 綁定類型的非常好的文章。
我創建的 WSDL 看起來像這樣:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://foo.com"
xmlns:tns="http://foo.com"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- Define the XML types we need to send and receive (used by the message definitions below) -->
<wsdl:types>
<schema targetNamespace="http://foo.com" xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<!-- Reusable types -->
<complexType name="ResponseType">
<sequence>
<element name="messageId" nillable="true" type="xsd:string" />
<element name="status" nillable="true" type="xsd:string" />
</sequence>
</complexType>
<complexType name="InputType">
<sequence>
<element name="firstName" nillable="true" type="xsd:string" />
<element name="lastName" nillable="true" type="xsd:string" />
<element name="command" nillable="true" type="xsd:string" />
</sequence>
</complexType>
<!-- Specific input/output elements used in wsdl:message definitions -->
<element name="serviceResponse">
<complexType>
<sequence>
<element name="messageReturn" type="tns:ResponseType" />
</sequence>
</complexType>
</element>
<element name="serviceRequest">
<complexType>
<sequence>
<element name="message" type="tns:InputType" />
</sequence>
</complexType>
</element>
</schema>
</wsdl:types>
<!-- Define the WSDL messages we send/receive (used by the port definition below) -->
<wsdl:message name="serviceResponseMessage">
<wsdl:part name="part1Name" element="tns:serviceResponse" />
</wsdl:message>
<wsdl:message name="serviceRequestMessage">
<wsdl:part name="part1name" element="tns:serviceRequest" />
</wsdl:message>
<!-- Define the WSDL port (used by the binding definition below) -->
<wsdl:portType name="ServicePort">
<wsdl:operation name="serviceOperation">
<wsdl:input message="tns:serviceRequestMessage" />
<wsdl:output message="tns:serviceResponseMessage" />
</wsdl:operation>
</wsdl:portType>
<!-- Define the WSDL binding of the port (used by the service definition below) -->
<wsdl:binding name="ServiceSoapBinding" type="tns:ServicePort">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="serviceOperation">
<wsdlsoap:operation soapAction="" />
<wsdl:input>
<wsdlsoap:body use="literal" />
</wsdl:input>
<wsdl:output>
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- Finally, define the actual WSDL service! -->
<wsdl:service name="UserCommandService">
<wsdl:port binding="tns:ServiceSoapBinding" name="ServicePort">
<!-- This address is just a placeholder, since the actual target URL will be specified at runtime -->
<wsdlsoap:address location="http://localhost:8080/blah" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
使用自定義 WSDL,我能夠使用 wsimport 生成與服務完美配合的客戶端存根。 同樣,使用包裝的 doc-literal 方法,我可以完全控制請求/響應的預期結構和命名空間,因此如有必要,我可以在該 XML 中實現多個命名空間。
享受...
我遇到了同樣的問題,就我而言,我的 Java 服務期望沒有命名空間的 xml 元素,但該服務正在響應命名空間。 我通過添加 @XmlElement 注釋設置預期的命名空間和元素名稱來修復,如下所示:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MyResponseType", propOrder = { "someProp" })
public class MyResponseType {
@XmlElement(namespace = "http://www.your-namespace.com/schema/v1.0", name = "someProp")
protected Integer someProp;
}
如果我的用例不正確,請糾正我。
您可以解組:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<ns1:result>6003</ns1:result>
<ns1:ndserr />
<ns1:transid>61437594</ns1:transid>
<ns1:descriptionerr>BLAH.</ns1:descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
但不能解組:
<?xml version="1.0" encoding="UTF-8"?>
<ns1:opINFOWLResponse xmlns:ns1="http://www.acme.com/ws"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:responseINFOWL xsi:type="ns1:responseINFOWL">
<result>6003</result>
<ndserr />
<transid>61437594</transid>
<descriptionerr>BLAH.</descriptionerr>
</ns1:responseINFOWL>
</ns1:opINFOWLResponse>
這意味着 JAXB 映射中的命名空間限定不正確。 以下可能有幫助:
如果您可以發布映射到此 XML 部分的類,以及package-info
類(如果有),那么我可以幫助您修改映射。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.