Why is Jackson using the wrong element name when serializing?

Tags: , ,



I have a Object that I would like Jackson to serialize like this…

<AccountsResponse>
    <accounts>
        <account/>
        <account>
            <userId>user</userId>
            ...
        </account>
    </accounts>
</AccountsResponse>

To try this I create the following class…

@Getter
@Setter
@ToString
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Payload {
    @JacksonXmlProperty(localName = "errormessage")
    private String errorMessage;
}


@Getter
@Setter
@ToString
public class AccountsResponse extends Payload{
    @JsonIgnore
    private static Logger LOGGER = LogManager.getLogger(AccountsResponse.class);

    @JacksonXmlProperty(localName = "accounts")
    private List<Account> accounts = Lists.newArrayList();
    public static AccountsResponse mapFromResultSet(ResultSet rs)
            throws SQLException
    {
        AccountsResponse response = new AccountsResponse();
        do {
            Account acct = Account.mapFromResultSet(rs);
            response.getAccounts().add(acct);
        } while (rs.next());
        return response;
    }
    public String toXml() throws JsonProcessingException {
        ObjectMapper mapper = new XmlMapper();
        return mapper.writeValueAsString(this);
    }
}

@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Account extends ResultSetParser{
    ...
}

But when I serialize I get…

<AccountsResponse>
    <accounts>
        <accounts/>
        <accounts>
            <userId>user</userId>
            ...
        </accounts>
    </accounts>
</AccountsResponse>

As you can see the problem here is the child tags should be account but in fact are accounts. I tried hacking around with the localname but can’t find the right mixture of VooDoo. What am I doing wrong?

Answer

I would change annotations on account list in AccountsResponse:

public class AccountsResponse extends Payload{

    @JacksonXmlElementWrapper(localName = "accounts")
    @JacksonXmlProperty(localName = "account")
    private List<Account> accounts = Lists.newArrayList();

}


Source: stackoverflow