2012-02-04 61 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