dinup24
dinup24

Reputation: 1772

Jackson: Array list wrapper in JAX-RS application

The following REST API list service returns a list of Messages. Using Jackson XML serializer, the response list generated with <ArrayList> warapper element. But, I require a JAXB style output with plural wrapper element <Messages>. Is it possible to achieve this without the need to create a wrapper Messages class.

@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getMessages() throws Exception {
    List<Messages> messages = new ArrayList<Messages>();
    messages.add(new Message("abc"));
    messages.add(new Message("xyz"));
    messages.add(new Message("pqr"));

    return Response.status(200).entity(messages).build();
}

public class Message {
    @JacksonXmlProperty
    private String msg;

    public String getMsg() {
        return msg;
    }
    public void setName(String msg) {
        this.msg = msg;
    }

    public Message(String msg) {
        this.msg = msg;
    }
}

Observed output:

<ArrayList>
    <item>
        <Msg>abc</Msg>
    </item>
    <item>
        <Msg>xyz</Msg>
    </item>
    <item>
        <Msg>pqr</Msg>
    </item>
</ArrayList>

Expected output:

<Messages>
    <Message>
        <Msg>abc</Msg>
    </Message>
    <Message>
        <Msg>xyz</Msg>
    </Message>
    <Message>
        <Msg>pqr</Msg>
    </Message>
</Messages>

Upvotes: 2

Views: 1856

Answers (1)

mp911de
mp911de

Reputation: 18137

There is no JAX-RS 1.x solution, but frameworks like RESTEasy provide own annotations for this like:

@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Wrapped(element = "Messages")
public Response getMessages() throws Exception {

You could also create an own wrapper data structure. If you need separate structures for XML and JSON, you probably would like to split the methods. One for generating JSON and one for XML.

Aligning JSON and XML is somewhat tricky, and there are some limitations that you can not overcome with maintaining one method only.

Another alternative could be:

@XmlRootElement(name = "Messags")
public class Messages {
    @XmlElement(name="Message");
    @JsonProperty("Messages")
    List<Message> messages = new ArrayList<>;
}

This would result in: XML:

<Messages>
    <Message>
        <Msg>abc</Msg>
    </Message>
    <Message>
        <Msg>xyz</Msg>
    </Message>
    <Message>
        <Msg>pqr</Msg>
    </Message>
</Messages>

JSON:

{
    "Messages": [{"Msg":"abc"}, ...]
}

Upvotes: 2

Related Questions