2011-08-24 2 views
7

wsimport를 사용하여 클라이언트를 생성하는 제 3 자 웹 서비스가 있습니다. webservice에 대한 각 호출은 성공적으로 완료되지만 반환되는 응답 객체는 모든 필드가 null로 설정됩니다. 네트워크 모니터링 나는 응답 메시지의 모든 XML 엘리먼트에 값이 있다는 것을 확인할 수있다. 따라서 객체는 null이 아닌 데이터를 가져야한다. 또한 old axis1로 생성되고 동일한 데이터로 호출 된 동일한 서비스에 대한 클라이언트는 비어 있지 않은 응답을 반환합니다. 어떤 생각인지 알 겠어? (차이가 나는 경우 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에 정렬 화합니다. 그냥 재미를 위해 I합니다 (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와 목시와 같은 동작. 아직도 무엇이 잘못되었는지 전혀 모릅니다.

업데이트 (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가 생성했습니다. 재미있는 점은 동일한 제 3 자의 다른 서비스가 정상적으로 작동한다는 것입니다. – 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> 

을 할 수 있지만, 비 정렬 화되지 :

당신은 비 정렬 화 수 이것은 당신의 JAXB 매핑의 네임 스페이스 자격이 잘못된 것을 의미

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

. 다음은 도움이 될 수

가있는 경우 당신은 XML의이 부분에 매핑되는 클래스와 package-info 클래스를 게시 할 수 있다면, 난 당신이 매핑을 수정할 수 있습니다.

2

최근 발생한 문제와 똑같은 문제가 발생했으며, 내가 접촉 한 서비스가 WSDL에서 광고 한 내용과 다른 것을 리턴하고 있다는 사실이 드러났습니다. 이 서비스는 현재 JAX-WS 구현과 충돌하는 이전 버전의 Apache Axis (1.4)를 사용했습니다.

특히 실제 응답 본문 내용의 네임 스페이스는 JAX-WS의 wsimport 유틸리티에서 생성 된 클라이언트 코드에서 예상 한 것과 다릅니다. , wsimport에 의해 생성 된 클라이언트 스텁 같은 것을 실제로 돌아오고 있었는지는 달리

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

기대하고 있었다

예를 들어, 실제 응답은 serviceResponse 및 네임 스페이스 " http://foo.com"의 모든 자식이 같은 무언가를 보았다 아래 응답은 네임 스페이스 " 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> 

내가 소모 된 서비스를 변경할 수 있기 때문에

, 내가 대신 썼다 사용되는 새로운 WSDL 자신을 감싸 문서 - 문자 (물론, 요청) 명시 적으로 예상되는 응답의 구조를 제어하는 ​​바인딩. IBM Developerworks.

나는 이런 식으로 뭔가 보였다 생성 된 WSDL을 통해 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> 

은, 내가 완벽하게 작동 클라이언트 스텁을 생성하기 위해 wsimport의를 사용할 수 있었다 서비스와. 또한 래핑 된 doc-literal 접근 방식을 사용하여 요청/응답의 예상되는 구조와 네임 스페이스를 완전히 제어하므로 필요한 경우 XML에 여러 네임 스페이스를 구현할 수 있습니다.

Enjoy ...

관련 문제