Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regarding REST response and XMLElement

I have below a REST response which needs to be created in the code:

<sample>
   <tags> 
       <tag>
           <name>ABC</name>
           <Date>2014-10-14T12:30:05Z</ingress>
       </tag>
       <tag>
           <name>DEF</name>
           <Date>2014-10-14T12:30:05Z</ingress>
       </tag>
   </tags>
</sample>

However,I am getting

<sample>
    <tags>           
        <name>ABC</name>
        <Date>2014-10-14T12:30:05Z</ingress>
    </tags>
    <tags>
        <name>DEF</name>
        <Date>2014-10-14T12:30:05Z</ingress>        
    </tags>
</sample>

in the response.Can someone please help me how the declaration of Java class to get the desired REST response ?

Here is the java code:

@XmlRootElement(name = "sample")
public class Sample {
    private List<Tag> tags;

    @XmlElement(name = "tags")
    public List<Tag> getTags() {
        return tags;
    }

    /**
     * @param tags
     *            the tags to set
     */
    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }

}

@XmlRootElement(name = "tag")
public class Tag {
    private String name;
    private Date date;

    /**
     * @return the name
     */
    @XmlElement(name = "name")
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the date
     */
    @XmlElement(name = "date")
    public Date getDate() {
        return date;
    }

    /**
     * @param date
     *            the date to set
     */
    public void setDate(Date date) {
        this.date = date;
    }
}

Thanks

like image 237
user3062513 Avatar asked Sep 29 '22 15:09

user3062513


2 Answers

@XmlElement(name = "tags")
List<Tag> tags;

It basically reads, for each item in the list, create a element named <tags>. So in essence, all you have is a <subject> element wrapping multiple <tags>.

A couple options to get another "upper-level" element

You can create a "upper-level" class to represent that, say Tags

public class Tags {
    protected List<Tag> tags;

    @XmlElement(name = "tag")
    public List<Tag> getTags() {
        if (tags == null) {
            tags = new ArrayList<>();
        }
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }
}

Then have an instance of Tags as a property of Sample

@XmlRootElement(name = "sample")
public class Sample {
    private Tags tags;

    @XmlElement(name = "tags")
    public void setTags(Tags tags) {
        this.tags = tags;
    }

    public Tags getTags() {
        return tags;
    }
}

OR

An even simpler solution is just to use @XmlElementWrapper

Generates a wrapper element around XML representation. This is primarily intended to be used to produce a wrapper XML element around collections

Using your original code, you can simple add the annotation to the list

@XmlRootElement(name = "sample")
public class Sample {
   private List<Tag> tags;

    @XmlElementWrapper(name = "tags")
    @XmlElement(name = "tag")
    public List<Tag> getTags() {
        if (tags == null) {
            tags = new ArrayList<>();
        }
        return tags;
    }

    public void setTags(List<Tag> tags) {
        this.tags = tags;
    }
}
like image 127
Paul Samsotha Avatar answered Oct 18 '22 03:10

Paul Samsotha


You can simply use the @XmlElementWrapper annotation to add a grouping element to your collection.

@XmlElementWrapper
@XmlElement(name = "tag")
public List<Tag> getTags() {
    return tags;
}

Note: @XmlElement applies to each item in the collection.

like image 44
bdoughan Avatar answered Oct 18 '22 01:10

bdoughan