2012-02-04 59 views
2

編輯:我原本遺漏了什麼可能是從我的問題,一個重要的細節 - 我的服務方法,返回的Java對象進行編組返回的接口類型(Foo),而比類實現類型(FooImpl)。JAX-B:缺少XML的子元素屬性

我有JAX-B註解一個簡單的Java類的幾個元素和屬性:

@XmlRootElement(name = "foo") 
public class FooImpl { 
    private String id; 
    private String name; 

    @XmlElement 
    public String getName() { 
      return name; 
    } 

    public void setName(final String name) { 
      this.name = name; 
    } 

    @XmlAttribute 
    public String getId() { 
      return Id; 
    } 

    public void setId(final String id) { 
      this.id = id; 
    } 
} 

編輯:FooImpl類有一個名爲Foo接口:

public interface Foo { 
    public String getName(); 
    public void setName(final String name); 

    public String getId(); 
    public void setId(final String id); 
} 

當我有一個服務方法,返回Foo,我得到我所期望的:

<foo id="abc123"> 
    <name>bar</name> 
</foo> 

但我也有另一個類包含一個List<Foo>,並且當它被編組時,foo的XML元素不包含它們的id屬性 !!

<foos> 
    <foo> 
     <name>bar1</name> 
    </foo> 
    <foo> 
     <name>bar2</name> 
    </foo> 
</foos> 

持有該列表中的類看起來是這樣的:

@XmlRootElement(name = "foos") 
public class Foos { 

    private List<Foo> foos; 

    @XmlElement(name = "foo") 
    public List<Foo> getFoos() { 
     return foos; 
    } 

    public void setFoos(List<Foo> foos) { 
     this.foos = foos; 
    } 

} 

我碰巧使用莫西作爲我的JAX-B實現,但我不認爲事情。

+2

確定在內存中(前編組)對象包含了'id'屬性非空值? – 2012-02-04 00:34:00

+0

是的。我可以自己返回任何一個'Foo'對象並查看屬性值。但是當同一個物體是'Foos'集合的一部分時,我不能。我正在通過HTTP4E直接從Eclipse測試Web服務,所以我可以精確地看到有效負載。 – HDave 2012-02-04 03:56:59

回答

4

備註:我是EclipseLink JAXB (MOXy)的領導者和JAXB (JSR-222)專家組的成員。

既然你有,它的類型是你將需要在@XmlElement註釋指定實現類型的接口屬性:

@XmlElement(name = "foo", type=FooImpl.class) 
public List<Foo> getFoos() { 
    return foos; 
} 

下面是一個完整的例子:

FOOS

package forum9137171; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "foos") 
public class Foos { 

    private List<Foo> foos; 

    @XmlElement(name = "foo", type=FooImpl.class) 
    public List<Foo> getFoos() { 
     return foos; 
    } 

    public void setFoos(List<Foo> foos) { 
     this.foos = foos; 
    } 

} 

Foo

package forum9137171; 

public interface Foo { 
    public String getName(); 
    public void setName(final String name); 

    public String getId(); 
    public void setId(final String id); 
} 

FoomImpl

package forum9137171; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "foo") 
public class FooImpl implements Foo { 
    private String id; 
    private String name; 

    @XmlElement 
    public String getName() { 
      return name; 
    } 

    public void setName(final String name) { 
      this.name = name; 
    } 

    @XmlAttribute 
    public String getId() { 
      return id; 
    } 

    public void setId(final String id) { 
      this.id = id; 
    } 
} 

演示

package forum9137171; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Foos.class); 
     System.out.println(jc); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum9137171/input.xml"); 
     Foos foos = (Foos) unmarshaller.unmarshal(xml); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(foos, System.out); 
    } 

} 

輸入/輸出

[email protected] 
<?xml version="1.0" encoding="UTF-8"?> 
<foos> 
    <foo id="abc123"> 
     <name>bar1</name> 
    </foo> 
    <foo id="def456"> 
     <name>bar2</name> 
    </foo> 
</foos> 

更多信息

+1

感謝您的快速回復。知道我的註釋或期望沒有任何問題是很有幫助的。它必須是我的環境中的東西。我將嘗試創建一個可重複的測試用例。 – HDave 2012-02-04 17:23:27

+0

在創建可重複的測試用例時,我發現我的代碼與原始問題中縮小的代碼之間存在潛在的重要差異。請參閱我上面的編輯。 Foo是一個由FooImpl類實現的接口。我只在FooImpl上只有JAX-B註釋。還要注意,返回'Foo'的服務方法工作...但是返回'List '的服務方法沒有。 – HDave 2012-02-05 02:13:29

+0

@HDave - 我根據您的意見更新了我的答案。 – 2012-02-05 10:50:06