我的jax-ws web服务客户端只返回空对象
我有第三方web服务,我使用wsimport生成客户端。每次对web服务的调用都会成功完成,但我返回的响应对象将其所有字段设置为null。监视网络我可以看到,响应消息中的所有XML元素都有值,因此对象应该包含非空数据。此外,使用旧的axis1生成的相同服务的客户端使用相同的数据调用将返回非空的响应。任何想法发生了什么? (如果它有什么区别,我使用MOXy的JAXB实现)。我的jax-ws web服务客户端只返回空对象
更新:我已经能够缩小它。 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
的命名空间,但仍然没有喜悦的相关部分。
如果我的用例不正确,请纠正我。
可以解组:
<?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
类,如果有一个的话,我可以帮你修改的映射。
我最近遇到了与您遇到的完全相同的问题,这是因为我所联系的服务正在返回与其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生成客户端存根被期待着什么样下面的响应,命名空间“http://foo.com”中的serviceResponse元素和匿名命名空间中包含的子消息返回元素。
<?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自己包裹文档文字(当然和要求,)结合明确地控制反应的预期结构。有超过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生成工作完全客户端存根与服务。而且,通过包装文档 - 文字方法,我完全控制了请求/响应的预期结构和名称空间,所以如果需要,我可以在该XML中实现多个名称空间。
享受...
你能提供消息和类的样本吗?这将有助于确定映射中不匹配的位置。 –
也许我可以发布适当的匿名wsdl文件和测试类,我的情况下的其他一切都是由wsimport生成的。有趣的是来自同一第三方的其他服务正常工作。 – agnul