【问题标题】:JAXB annotations for the following XML以下 XML 的 JAXB 注释
【发布时间】:2011-10-12 00:43:09
【问题描述】:

我花了一段时间试图让它工作,但我运气不佳。

我有以下 XML:

<message>
  <buckets>
    <bucket>
      <channels>
         <channel>Test A</channel>
         <channel>Test B</channel>
      </channels>
      <messageText>This is sample text</messageText>
    </bucket>
    <bucket>
      ....
    </bucket>
  </buckets>
  <userId>10</userId>
 </message>

我正在尝试使用 JAXB 注释将其映射到 POJO,但遇到了问题。

我的班级如下:

@XmlRootElement(name="message")
public class MessageRS {

  public static class Bucket {
    private List<String>channels;
    private String text;

    private Bucket() {}

    public List<String> getChannels() { .... }
    public void setChannels(List<String> channels) { .... }
    public String getText() { .... }
    public void setText(String text) { .... }
  }

  private List<Bucket> buckets;

  private Long userId;

  private MessageRS() { }

  public List<Bucket getBuckets() { .... }
  public void setBuckets(List<Bucket> buckets) { .... }
  public long geUserId() { .... }
  public void setUserId(long UserId { .... }
}

很遗憾,这似乎无法正常工作。我将如何注释它以正确地将 XML 映射到该对象(所需的映射应该很明显)?

这里没有什么是一成不变的——此时我可以随意更改 XML 和 Java 类结构。

【问题讨论】:

    标签: java xml annotations jaxb pojo


    【解决方案1】:

    试试这个:

    import javax.xml.bind.JAXBContext;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlElementWrapper;
    import javax.xml.bind.annotation.XmlRootElement;
    import java.io.StringWriter;
    import java.util.Arrays;
    import java.util.List;
    
    public class JaxbStuff {
        public static void main(String[] args) throws Exception {
            MessageRS message = new MessageRS();
            message.setUserId(10);
            MessageRS.Bucket bucket1 = new MessageRS.Bucket();
            bucket1.setText("This is sample text");
            bucket1.setChannels(Arrays.asList("Test A", "Test B"));
            MessageRS.Bucket bucket2 = new MessageRS.Bucket();
            bucket2.setText("Some more text");
            bucket2.setChannels(Arrays.asList("1", "2"));
            message.setBuckets(Arrays.asList(bucket1, bucket2));
            StringWriter writer = new StringWriter();
            JAXBContext.newInstance(MessageRS.class).createMarshaller().marshal(message, writer);
            System.out.println(writer);
        }
    
        @XmlRootElement(name = "message")
        static class MessageRS {
    
            public static class Bucket {
                private List<String> channels;
                private String text;
    
                private Bucket() {}
    
                @XmlElementWrapper(name = "channels")
                @XmlElement(name = "channel")
                public List<String> getChannels() {
                    return channels;
                }
    
                public void setChannels(List<String> channels) {
                    this.channels = channels;
                }
    
                public String getText() {
                    return text;
                }
    
                public void setText(String text) {
                    this.text = text;
                }
            }
    
            private List<Bucket> buckets;
    
            private Long userId;
    
            private MessageRS() { }
    
            public List<Bucket> getBuckets() {
                return buckets;
            }
    
            public void setBuckets(List<Bucket> buckets) {
                this.buckets = buckets;
            }
    
            public long getUserId() {
                return userId;
            }
    
            public void setUserId(long UserId) {
                this.userId = UserId;
            }
        }
    
    }
    

    您在getUserId() 中也有错字,这会导致该属性无法正常工作。是geUserId()

    另外,像这样混合 Long 和 long 是很危险的。如果您的 userId 为 null 并且您调用 getUserId(),它将抛出 NullPointerException。

    【讨论】:

    • 好电话。不知道为什么我认为这适用于 JAXB。
    • 是的,实际代码在另一台 PC 上,所以我只是在编辑器中再次输入...
    • 无论如何,在将 XMLElementWrapper 和 XMLElement 属性也添加到 getBuckets() 方法后,您的解决方案工作正常。
    【解决方案2】:

    通常,jaxb 使用列表周围的包装对象。因此,您将拥有一个具有 List&lt;Bucket&gt; getBuckets() 的 Buckets 类,并且您将拥有一个具有 List&lt;Channel&gt; getChannels() 的 Channels 类。我相信你可以使用额外的注释来避免额外的包装类,但它们并不经常使用(至少不被常见的自动生成工具使用)。

    就个人而言,我发现编写 xml 模式并使用 xjc 生成 java 类要简单得多。

    【讨论】:

    • “不常用”?根据谁?创建自己的集合类的唯一充分理由是,如果您需要它们作为根元素。这里不是这样。
    • “不常用”可能是一个不好的词选择。 xjc 不使用该注释,并且我使用的大部分 jaxb 代码是自动生成的(通常由 xjc 生成)。
    • 啊,我明白了。我正好在硬币的反面。我从来没有用过xjc。我只是在泽西岛使用 JAXB 进行编组/解组。
    猜你喜欢
    • 1970-01-01
    • 2016-08-31
    • 1970-01-01
    • 1970-01-01
    • 2014-03-22
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多