Scyla101
Scyla101

Reputation: 242

JAXB: easy way to annotate name of element tags for object lists

I was looking into a way to easily change the element name of a list of objects with JAXB when publishing them through a web service. Here is the example:

Say I have an object I want to serialize to XML:

@XmlRootElement(name = "greeting")
public class TestClassForSo {

    public String id;
    public List<String> description;
}

And I have a web service that publishes a list of these objects as XML:

@GET
@Path("/so-test")
@Produces({AgiMediaType.APPLICATION_XML, AgiMediaType.APPLICATION_JSON})
@XmlElementWrapper(name = "wrapperName")
public List<TestClassForSo> getGreetings() {

    List<TestClassForSo> greetingList = new ArrayList<>();

    TestClassForSo greeting = new TestClassForSo();

    String id = "hello-word";
    List<String> greetings = new ArrayList<>(Arrays.asList("Hello World,
                                                            Bonjour le monde,
                                                            Hallo Welt, 
                                                            Hola Mundo"));

    greeting.id = id;
    greeting.description = greetings;

    greetingList.add(greeting);

    return greetingList;
}

I get the following result when I request the resource through an HTTP GET call:

<testClassForSoes>
    <greeting>
        <id>hello-word</id>
        <description>Hello World, Bonjour le monde, Hallo Welt, Hola Mundo</description>
    </greeting>
</testClassForSoes>

Is there an easy way to change the element name of the list to greetings other than putting it into a wrapper method or write my own serialization mechanism etc?

Obviously I'm unable to change the name of the TestClassForSo due to naming conventions.

As a side question would this problem really matter besides making it more readable for human beings what the element name of the list is?

Thank you for looking into the question. Any help is appreciated. I've looked into similar questions on the web but nothing seems to fit my problem exactly.

Greetings

Upvotes: 0

Views: 67

Answers (1)

diogo
diogo

Reputation: 3977

As already stated here:

You can't achieve this with only JAXB, since the annotation would have to be put on the ArrayList class itself.

The solution would be with the use of Jackson ObjectWriter's method: withRootName()


However, I think is pretty much simpler creating your own wrapper class for this, since Jersey doesn't allow root name customization:

@XmlRootElement(name = "greetings")
public class RootClass {

    @XmlElement(name = "greeting")
    public List<TestClassForSo> greetingList;

}

and change your method's strategy to the following, e.g:

@GET
@Path("/so-test")
@Produces({AgiMediaType.APPLICATION_XML, AgiMediaType.APPLICATION_JSON})
public RootClass getGreetings() {
    List<TestClassForSo> greetingList = new ArrayList<>();

    for (int i = 0; i < 3; i++) {
        TestClassForSo testClassForSo = new TestClassForSo();

        String id = "hello-word";
        List<String> greetings = new ArrayList<>(Arrays.asList("Hello World " + i));
        testClassForSo.id = id;
        testClassForSo.description = greetings;

        greetingList.add(testClassForSo);
    }

    RootClass r = new RootClass();
    r.greetingList = greetingList;
    return r;
}

Then, we'd have the final result:

<greetings>
    <greeting>
        <id>hello-word</id>
        <description>Hello World 0</description>
    </greeting>
    <greeting>
        <id>hello-word</id>
        <description>Hello World 1</description>
    </greeting>
    <greeting>
        <id>hello-word</id>
        <description>Hello World 2</description>
    </greeting>
</greetings>

Upvotes: 1

Related Questions