2011-08-24 11 views
7

wsimportを使用してクライアントを生成するサードパーティのWebサービスがあります。 Webサービスへの各呼び出しは正常に完了しましたが、返される応答オブジェクトはすべてのフィールドがnullに設定されています。ネットワークの監視私は、応答メッセージのXML要素のすべてに値が入っているので、オブジェクトにnull以外のデータが含まれていることがわかります。また、old1で生成され、同じデータで呼び出された同じサービスのクライアントは、空ではない応答を返します。何が起きているのか? (それが何か違いがある場合はMOXyのJAXB実装を使用しています)。私のjax-ws webserviceクライアントは空のオブジェクトだけを返します

更新:私はそれを絞り込むことができました。 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 ... 

で、nullに設定されているすべてのフィールドがnull以外responseINFOWLオブジェクトをラップするnull以外OpINFOWLResponseに非整列化です。ちょうど楽しみのために私は

(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; 

であり、これは私がpackage-infoで名前空間が、まだありません喜びで少し遊んでみました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. 

} 

の関連する部分です。

+0

メッセージとクラスのサンプルを提供できますか?これは、マッピングの不一致がどこにあるかを判断するのに役立ちます。 –

+0

私は適切に匿名化されたwsdlファイルとテストクラスを投稿することができました。私の場合はwsimportによって生成されます。面白いことは、同じサードパーティの他のサービスがうまく動作することです。 – agnul

答えて

1

あなたのユースケースが間違っている場合は、私に修正してください。

あなたは非整列化することができます:

<?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クラスを投稿することができれば、その後、私はあなたがマッピングを変更することができます。

2

私は最近あなたが遭遇したのとまったく同じ問題に遭遇しました。私が接触していたサービスが、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要素と、匿名ネームスペースの子の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> 

私が消費したサービスを変更できませんでしたので、私の代わりに自分自身が明示的に(もちろん、要求、)予想される応答の構造を制御するために包まれたのdoc-literalバインディングを使用し、新しい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のを使用することができましたサービスと一緒に。また、ラップされたdoc-literalアプローチでは、要求/応答の予想される構造と名前空間を完全に制御するので、必要に応じてそのXMLに複数の名前空間を実装できます。

お楽しみください...

関連する問題