2011-08-24 23 views
7

Tôi có dịch vụ web của bên thứ ba mà tôi tạo khách hàng bằng cách sử dụng wsimport. Mỗi cuộc gọi đến webservice hoàn tất thành công, nhưng đối tượng phản hồi mà tôi nhận lại có tất cả các trường của nó được đặt thành rỗng. Giám sát mạng Tôi có thể thấy rằng trên dây tất cả các phần tử XML trong thông điệp phản hồi có các giá trị trong chúng, vì vậy đối tượng phải có dữ liệu không rỗng trong nó. Ngoài ra, một khách hàng cho cùng một dịch vụ được tạo với trục cũ1 và được gọi với cùng một dữ liệu trả về một phản hồi không trống. Bất kỳ ý tưởng gì đang xảy ra? (Trong trường hợp nó làm cho bất kỳ sự khác biệt tôi đang sử dụng thực hiện của MOXy của JAXB).Máy khách webservice jax-ws của tôi chỉ trả về các đối tượng trống

Cập nhật: Tôi đã có thể thu hẹp nó xuống. Wsdl định nghĩa đối tượng trong không gian tên riêng của nó, giả sử http://www.acme.com/ws. Câu trả lời tôi nhận được từ các dịch vụ là

<?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 ... 

và là unmarshalled để một tổ chức phi rỗng OpINFOWLResponse bao bọc xung quanh một đối tượng phi rỗng responseINFOWL với tất cả các lĩnh vực thiết lập để null. Chỉ cần cho vui, tôi đã cố gắng viết một vài dòng để unmarshal đoạn trên (sau khi tước phí SOAP)

JAXBContext ctx = JAXBContext.newInstance(OpINFOWLResponse.class); 
Unmarshaller u = ctx.createUnmarshaller(); 

OpINFOWLResponse o = (OpINFOWLResponse) u.unmarshal(new StringReader(theSnippetAbove)); 
ResponseINFOWL w = o.getResponseINFOWL(); 

và tôi nhận được kết quả tương tự. Nếu tôi thay đổi XML ở trên thành

<?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> 

Mọi thứ đều hoạt động tốt. Rất tiếc.

Cập nhật (lần nữa): Hành vi tương tự với cả jaxb-RI và Moxy. Vẫn không có ý tưởng gì sai.

Cập nhật (ngày 09 tháng chín): Các gợi ý dưới đây về giấy chứng nhận namespace là sai là thú vị, nhưng tôi phải wsimport sẽ nhận được những điều đúng. Dù sao, đây là tôi 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; 

và đây là phần có liên quan của lớp ResponseINFOWL

/* 
* <p>Java class for responseINFOWL complex type. 
* 
* <p>The following schema fragment specifies the expected content contained within this class. 
* 
* <pre> 
* &lt;complexType name="responseINFOWL"> 
* &lt;complexContent> 
*  &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"> 
*  &lt;sequence> 
*   &lt;element name="result" type="{http://www.w3.org/2001/XMLSchema}string"/> 
*   &lt;element name="descriptionerr" type="{http://www.w3.org/2001/XMLSchema}string"/> 
*   &lt;element name="transid" type="{http://www.w3.org/2001/XMLSchema}string"/> 
*   &lt;element name="ndserr" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/> 
*   &lt;element name="wallet" type="{http://www.acme.com/ws}t_wallet" minOccurs="0"/> 
*  &lt;/sequence> 
*  &lt;/restriction> 
* &lt;/complexContent> 
* &lt;/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. 

} 

Tôi đã thử chơi một chút với các không gian tên trong package-info nhưng vẫn không có niềm vui.

+0

Bạn có thể cung cấp mẫu từ tin nhắn và lớp học không? Điều này sẽ giúp xác định vị trí không khớp trong ánh xạ. –

+0

Có lẽ tôi có thể đăng tập tin wsdl ẩn danh và lớp kiểm tra phù hợp, mọi thứ khác trong trường hợp của tôi được tạo bởi wsimport. Điều thú vị là các dịch vụ khác từ cùng một công việc của bên thứ ba tốt. – agnul

Trả lời

1

Vui lòng sửa tôi nếu tôi có trường hợp sử dụng của bạn không chính xác.

Bạn có thể unmarshal:

<?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> 

Nhưng không thể unmarshal:

<?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> 

Điều này có nghĩa rằng trình độ namespace trong ánh xạ JAXB của bạn là không chính xác. Sau đây có thể giúp:

Nếu bạn có thể đăng các lớp bản đồ để phần này của XML, và lớp package-info nếu có một, sau đó tôi có thể giúp bạn thay đổi ánh xạ.

2

Gần đây tôi đã gặp phải sự cố tương tự chính xác mà bạn gặp phải và thực tế là dịch vụ tôi đang liên hệ đã trả lại thứ gì đó khác với WSDL được quảng cáo. Dịch vụ đã sử dụng phiên bản Apache Axis cũ (1.4) với hành vi xung đột với các triển khai JAX-WS hiện tại.

Cụ thể, không gian tên trên nội dung nội dung phản hồi thực tế KHÔNG phải là những gì được mong đợi bởi mã máy khách được tạo bởi tiện ích wsimport của JAX-WS. Ví dụ, phản ứng thực tế nhìn một cái gì đó như thế này, với serviceResponse và tất cả các con của nó trong không gian tên "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> 

Ngược lại với những gì đã thực sự trở lại, các cuống client tạo ra bởi wsimport mong đợi một cái gì đó như câu trả lời bên dưới, với phần tử serviceResponse trong không gian tên "http://foo.com" và phần tử con messageReturn chứa trong không gian tên ẩn danh.

<?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> 

Vì tôi không thể thay đổi dịch vụ tôi đã được tiêu thụ, tôi thay vì viết một WSDL mới bản thân mình rằng sử dụng một gói doc-đen ràng buộc để kiểm soát một cách rõ ràng cơ cấu dự kiến ​​của phản ứng (và yêu cầu, tất nhiên). Có một bài viết thực sự tốt trên các loại ràng buộc WSDL qua IBM Developerworks.

WSDL Tôi tạo ra nhìn một cái gì đó như thế này:

<?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> 

Với WSDL tùy chỉnh, tôi đã có thể sử dụng wsimport để tạo cuống khách hàng mà hoạt động hoàn hảo với dịch vụ. Đồng thời, với cách tiếp cận doc-literal được bao bọc, tôi hoàn toàn kiểm soát cấu trúc và không gian tên mong đợi của yêu cầu/phản hồi, vì vậy tôi có thể triển khai nhiều không gian tên trong XML đó nếu cần.

Thưởng thức ...

Các vấn đề liên quan