2017-06-07 10 views
2

次のコードはキャスト例外を引き起こしていますが、その理由はわかりません。 ParameterValueList内のオブジェクトは、JAXBオブジェクトParameterValueStructに対して熱心にアンマーシャリングする必要がありますが、そうではありません。すべてがsoapエンコーディングとcwmpスキーマファイルから直接生成されました。JAXB anyTypeはキャストに失敗します

誰にも提案はありますか?スレッド "メイン" とjava.lang.ClassCastExceptionで

public static void main(String[] args) throws JAXBException, FileNotFoundException 
{ 
    JAXBContext c = JAXBContext.newInstance("org.dslforum.cwmp_1_1"); 

    Unmarshaller u = c.createUnmarshaller(); 
    Inform inform = (Inform) u.unmarshal(new FileInputStream("test.xml")); 

    List<Object> list = inform.getParameterList().getAny(); 
    System.out.println(list); // prints [[ParameterValueStruct: null], ... 

    for (Object o : list) { 
     ParameterValueStruct pv = (ParameterValueStruct)o; // exception here 
     System.out.println(pv.getName()); 
    } 
} 

例外:com.sun.org.apache.xerces.internal.dom.ElementNSImplはテストでorg.dslforum.cwmp_1_1.ParameterValueStruct にキャストすることはできません.main(Test.java:26)

私はJavaのXJCツールを使用してhttp://schemas.xmlsoap.org/soap/encoding/から生成された、このクラスがあります。

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "Array", propOrder = { 
    "any" 
}) 
@XmlSeeAlso({ 
    ParameterValueList.class, 
}) 
public class Array { 

    @XmlAnyElement(lax = true) 
    protected List<Object> any; 
    @XmlAttribute(name = "id") 
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class) 
    @XmlID 
    @XmlSchemaType(name = "ID") 
    protected java.lang.String id; 
    @XmlAttribute(name = "href") 
    @XmlSchemaType(name = "anyURI") 
    protected java.lang.String href; 
    @XmlAttribute(name = "arrayType", namespace = "http://schemas.xmlsoap.org/soap/encoding/") 
    protected java.lang.String arrayType; 
    @XmlAttribute(name = "offset", namespace = "http://schemas.xmlsoap.org/soap/encoding/") 
    protected java.lang.String offset; 
    @XmlAnyAttribute 
    private Map<QName, java.lang.String> otherAttributes = new HashMap<QName, java.lang.String>(); 

    public List<Object> getAny() { 
     if (any == null) { 
      any = new ArrayList<Object>(); 
     } 
     return this.any; 
    } 
    .... 
} 

を私はLSOも同じツールを使用して生成されたこれら2つのクラスを持っていますが、https://www.broadband-forum.org/cwmp/cwmp-1-1.xsdから:

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "ParameterValueList") 
public class ParameterValueList 
    extends Array 
{ 
} 

セカンドファイル:

<?xml version="1.0"?> 
<cwmp:Inform xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:cwmp="urn:dslforum-org:cwmp-1-1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <ParameterList soap-enc:arrayType="cwmp:ParameterValueStruct[3]"> 
    <ParameterValueStruct> 
     <Name>Device.DHCPv4.ClientNumberOfEntries</Name> 
     <Value xsi:type="xsd:unsignedInt">0</Value> 
    </ParameterValueStruct> 
    <ParameterValueStruct> 
     <Name>Device.DNS.Client.ServerNumberOfEntries</Name> 
     <Value xsi:type="xsd:unsignedInt">1</Value> 
    </ParameterValueStruct> 
    <ParameterValueStruct> 
     <Name>Device.DeviceInfo.AdditionalSoftwareVersion</Name> 
     <Value xsi:type="xsd:string">DM: 532,SK: 2.6.33.9-rt31,SF: 251X 137.0,BK: 10</Value> 
    </ParameterValueStruct> 
    </ParameterList> 
</cwmp:Inform> 

答えて

2

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "ParameterValueStruct", propOrder = { 
    "name", 
    "value" 
}) 
public class ParameterValueStruct { 
    @XmlElement(name = "Name", required = true) 
    protected String name; 
    @XmlElement(name = "Value", required = true) 
    @XmlSchemaType(name = "anySimpleType") 
    protected Object value; 
    ... 
} 

そして、ここには私のtest.xmlファイルです

ParameterValueStructの前に@XmlRootElement(name="ParameterValueStruct",namespace="")を追加するだけでいいです。

ここではT package-info.java

@javax.xml.bind.annotation.XmlSchema(namespace = "urn:dslforum-org:cwmp-1-1") 
package org.dslforum.cwmp_1_1; 

のbecauce明示的namespace=""を必要とする彼の正しいクラスは次のようになります。

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "ParameterValueStruct", propOrder = { 
    "name", 
    "value" 
}) 
@XmlRootElement(name="ParameterValueStruct",namespace="") 
public class ParameterValueStruct { 
    @XmlElement(name = "Name", required = true) 
    protected String name; 
    @XmlElement(name = "Value", required = true) 
    @XmlSchemaType(name = "anySimpleType") 
    protected Object value; 
    ... 
} 

PS:およそ@XmlAnyElement(lax=true)

良くJAXB-チュートリアルのこの http://blog.bdoughan.com/2012/12/jaxbs-xmlanyelementlaxtrue-explained.htmlを参照してください。
+0

あなたの提案にnamespace = ""を追加して動作させる必要がありました。合計:@XmlRootElement(name = "ParameterValueStruct"、namespace = "") – ComputerEngineer88

+0

@ ComputerEngineer88すべてのクラスの名前空間を設定するpackage-info.javaが欠けています。 – Edwardth

+0

なぜ空の名前空間を指定する必要があるのか​​まだ分かりません。 ParameterValueStructがパッケージ内の他のクラスのようにキャスト可能であるようにこれを行う方法はありますか?つまり、空の名前空間を指定する必要はありませんか? – ComputerEngineer88

関連する問題