Reputation: 7539
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.
Upvotes: 1
Views: 1978
Reputation: 53674
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.
Upvotes: 0
Reputation: 128749
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.
Upvotes: 3