2012-01-31 5 views
14

ウェブサービスがあることをWSDLで定義されたオブジェクトを返している:私は、このオブジェクトのクラスの情報を印刷するときJAXBを使用しているサービスから返された 'anyType'からJavaオブジェクトを作成する方法は?

<s:complexType mixed="true"><s:sequence><s:any/></s:sequence></s:complexType> 

、それはとして起動します:

class com.sun.org.apache.xerces.internal.dom.ElementNSImpl 

しかし、私はこれをアンマーシャリングする必要があります次のクラスのオブジェクトとして:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
     "info", 
     "availability", 
     "rateDetails", 
     "reservation", 
     "cancellation", 
     "error" }) 
@XmlRootElement(name = "ArnResponse") 
public class ArnResponse { } 

私はマーシャルにどのようにこのオブジェクトのXMLを知っているので、私は、応答が正しいことを知っている:

プリントアウトし
Marshaller m = jc.createMarshaller(); 
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
m.marshal(rootResponse, System.out); 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:SubmitRequestDocResponse xmlns:ns2="http://tripauthority.com/hotel"> 
    <ns2:SubmitRequestDocResult> 
     <!-- below is the object I'm trying to unmarshall --> 
     <ArnResponse> 
      <Info /> 
      <Availability> 
       <!-- etc--> 
      </Availability> 
     </ArnResponse> 
    </ns2:SubmitRequestDocResult> 
</ns2:SubmitRequestDocResponse> 

をどのように私は私がそれを表している知っているArnResponseオブジェクトに見ているElementNSImplオブジェクトを回すことができますか?

さらに、私はファイルアクセスが制限されているAppEngine上で動作しています。任意のヘルプ

更新ため

ありがとう:私はそうのように、@XmlAnyElement(lax=true)注釈を追加しました

@XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "", propOrder = { 
     "content" 
    }) 
    @XmlSeeAlso(ArnResponse.class) 
    public static class SubmitRequestDocResult { 

    @XmlMixed 
    @XmlAnyElement(lax = true) 
    protected List<Object> content; 

しかし、それはどんな違いがありません。

これはコンテンツがListであるという事実と関係していますか?

は、ここで私は、サーバーから戻ってそれを取得した後、コンテンツにアクセスしようとしているコードです:

2012年1月31日10時04分:出力を持ってい

List list = rootResponse.getSubmitRequestDocResult().getContent(); 

for (Object o : list) { 
    ArnResponse response = (ArnResponse) o; 
    System.out.println(response); 
} 

: 14 AM com.districthp.core.server.ws.alliance.AllianceApi getRates SEVERE: com.sun.org.apache.xerces.internal.dom.ElementNSImplを com.districthp.core.server.wsにキャストできません。 alliance.response.ArnResponse

回答:

axtavtの答えは、トリックを行いました。これは働いていた:

Object content = ((List)result.getContent()).get(0); 
JAXBContext context = JAXBContext.newInstance(ArnResponse.class); 
Unmarshaller um = context.createUnmarshaller(); 
ArnResponse response = (ArnResponse)um.unmarshal((Node)content); 
System.out.println("response: " + response); 
+0

レスポンスオブジェクトとWSDLのすべてのスキーマのコピーがあります。 – Cuga

+4

ここで使用される 'Node'は' org.w3c.dom.Node'です。 –

答えて

14

あなたはUnmarshaller.unmarshal(Node)にそのオブジェクトを渡すことができ、それを非整列化することができるはずです。

+0

ねえ、うまくいきました。本当にありがとう! – Cuga

1

を私はXMLで作業していたものから、anyTypeは、任意のオブジェクトを表すことができ、あなたが戻ってそれをマッピングすることができます最も近いものはjava.lang.Objectです。 (その事実以外にも、anyTypeは技術的にセキュリティホールになる可能性があります。悪意のあるバイナリを含む何かを誰かに注入することを許可します。スキーマが許可するので、何も停止しません。)

スキーマを変更してカスタムオブジェクトへのマッピングを可能にすることをお勧めします。これは、プログラミングの観点、消費の観点、およびセキュリティの観点の両方からきれいです。

あなたはそれを行うことができませんが、私はあなたの要素の属性として型を格納することをお勧めします。 anyTypeをそのオブジェクトに戻すのに役立つようにカスタムコードを書く必要があるかもしれませんが、少なくともあなたはそのタイプを知っています。

2つのセントは私の経験に基づいています(ほとんどの場合、統合の分野です)。

+1

ええ、できれば 'anyType'は使用しませんが、他の誰かのスキーマと統合しているので、私たちはそれに固執しています。 – Cuga

4

@XmlAnyElement(lax=true)を使用できます。これにより、既知のルート要素(@XmlRootElementまたは@XmlElementDecl)を持つXMLがドメインオブジェクトに変換されます。たとえば、以下を参照してください

+1

私はチェックしましたが、注釈はすでにそこにありました。私の更新された質問を見てください。あなたの助けをもう一度感謝し、私は前にあなたのブログとあなたの他の答えを見てきました。あなたの仕事はすでに私を助けてくれました。 – Cuga

+0

ありがとう、それは私の問題を解決! –

関連する問題