I want to serialize a JSON-String I receive as a POJO, for further usage in my code, but I am struggling to get it working without writing a custom serializer.
I would prefer as solution without writing a custom serializer, but if that is the only possible way I will write one.
Additionally I believe the data I receive is a weird JSON since the list I request is not sent as list using []
but rather as a object using {}
.
I receive the following list/object (shortened):
{
"results": {
"ALL": {
"currencyName": "Albanian Lek",
"currencySymbol": "Lek",
"id": "ALL"
},
"XCD": {
"currencyName": "East Caribbean Dollar",
"currencySymbol": "$",
"id": "XCD"
},
"EUR": {
"currencyName": "Euro",
"currencySymbol": "â?¬",
"id": "EUR"
},
"BBD": {
"currencyName": "Barbadian Dollar",
"currencySymbol": "$",
"id": "BBD"
},
"BTN": {
"currencyName": "Bhutanese Ngultrum",
"id": "BTN"
},
"BND": {
"currencyName": "Brunei Dollar",
"currencySymbol": "$",
"id": "BND"
}
}
}
I created my first POJO for the inner object like this:
public class CurrencyDTO implements Serializable {
private String currencyName;
private String currencySymbol;
private String currencyId;
@JsonCreator
public CurrencyDTO( @JsonProperty( "currencyName" ) String currencyName, @JsonProperty( "currencySymbol" ) String currencySymbol,
@JsonProperty( "id" ) String currencyId )
{
this.currencyId = currencyId;
this.currencyName = currencyName;
this.currencySymbol = currencySymbol;
}
}
which itself is fine. Now I wrote another POJO as a wrapper for the data a layer above which looks like this:
public class CurrencyListDTO implements Serializable {
private List<Map<String, CurrencyDTO>> results;
public CurrencyListDTO()
{
}
}
Adding the annotations @JsonAnySetter or using the @JsonCreator didn't help either, so I removed them again and now I am wondering which little trick could enable the correct serialization of the json.
My Exception is the following:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token
at [Source: (String)"{"results":{"ALL":{"currencyName":"Albanian Lek","currencySymbol":"Lek","id":"ALL"},"XCD":{"currencyName":"East Caribbean Dollar","currencySymbol":"$","id":"XCD"},"EUR":{"currencyName":"Euro","currencySymbol":"â?¬","id":"EUR"},"BBD":{"currencyName":"Barbadian Dollar","currencySymbol":"$","id":"BBD"},"BTN":{"currencyName":"Bhutanese Ngultrum","id":"BTN"},"BND":{"currencyName":"Brunei Dollar","currencySymbol":"$","id":"BND"},"XAF":{"currencyName":"Central African CFA Franc","id":"XAF"},"CUP":{"cur"[truncated 10515 chars]; line: 1, column: 12] (through reference chain: com.nico.Banking.api.data.dto.CurrencyListDTO["results"])
You should change your CurrencyListDTO
to:
public class CurrencyListDTO {
private Map<String, CurrencyDTO> results;
// getters and setters
}
Because the results
field in the response object is another object with the currencyId
as key and no array.
You then can create your list of currencies like this:
ObjectMapper mapper = new ObjectMapper();
CurrencyListDTO result = mapper.readValue(json, CurrencyListDTO.class);
List<CurrencyDTO> currencies = new ArrayList<>(result.getResults().values());