【问题标题】:JAX-B: Missing XML attributes on child elementsJAX-B:子元素上缺少 XML 属性
【发布时间】:2012-02-04 00:10:24
【问题描述】:

编辑:我最初从我的问题中遗漏了一个重要的细节——返回要编组的 Java 对象的服务方法返回接口类型 (Foo) 而不是类实现类型(FooImpl)。

我有一个简单的 Java 类,其中包含几个元素和属性的 JAX-B 注释:

@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&lt;Foo&gt; 的类,当它被编组时,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;
    }

}

我碰巧使用 MOXy 作为我的 JAX-B 实现,但我认为这并不重要。

【问题讨论】:

  • 您确定内存中的对象(在编组之前)包含id 属性的非空值吗?
  • 是的。我可以自己返回任何一个Foo 对象并查看属性值。但是当同一个对象是Foos 集合的一部分时,我不能。我正在通过 HTTP4E 直接从 Eclipse 测试 Web 服务,因此我可以准确地看到有效负载。

标签: java xml web-services jaxb moxy


【解决方案1】:

注意:我是EclipseLink JAXB (MOXy) 领导,也是JAXB (JSR-222) 专家组的成员。

由于您有一个类型为接口的属性,您需要在 @XmlElement 注释上指定实现类型:

@XmlElement(name = "foo", type=FooImpl.class)
public List<Foo> getFoos() {
   return 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);
    }

}

输入/输出

org.eclipse.persistence.jaxb.JAXBContext@16a786
<?xml version="1.0" encoding="UTF-8"?>
<foos>
   <foo id="abc123">
      <name>bar1</name>
   </foo>
   <foo id="def456">
      <name>bar2</name>
   </foo>
</foos>

更多信息

【讨论】:

  • 感谢您的快速回复。知道我的注释或期望没有任何问题会很有帮助。它一定是我的环境中的东西。我将尝试创建一个可重现的测试用例。
  • 在创建可重现的测试用例时,我发现我的代码与原始问题中的缩小代码之间存在潜在的重要差异。请参阅我上面的编辑。 Foo 是一个由 FooImpl 类实现的接口。但是,我只有 FooImpl 上的 JAX-B 注释。另请注意,返回 Foo 的服务方法可以工作......但返回 List&lt;Foo&gt; 的服务方法不能。
  • 您的回答完美无缺...谢谢。我想这确实让我想知道为什么 JAXB 无法自行确定支持接口的实现类型。这也让我想知道为什么返回 Single Foo 曾经有效?!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多