简体   繁体   中英

JAXB annotations for the following XML

I've spent a while trying to get this to work however I've had little luck.

I have the following 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>

I'm trying to get this mapped to a POJO using JAXB annotations but am having trouble.

My class is as follows:

@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 { .... }
}

Unfortunately, this doesn't seem to be working correctly. How would I annotate this to correctly map the XML to this object (the desired mapping should be obvious)?

Nothing is set in stone here - I'm free to change both the XML and Java class structures at this point.

Try this:

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;
        }
    }

}

You also had a typo in getUserId() , which would make that property not work correctly. It was geUserId() .

Also, it's dangerous to mix Long and long like that. If your userId is null and you call getUserId() , it'll throw a NullPointerException.

typically, jaxb uses wrapper objects around lists. so, you would have a Buckets class which has List<Bucket> getBuckets() , and you would have a Channels class with List<Channel> getChannels() . i believe there are extra annotations you can use to avoid the extra wrapper classes, but they are not frequently used (at least not by the common auto-generation tools).

personally, i find it much simpler to write the xml schema and use xjc to generate the java classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM