Reputation: 2125
I'm trying to transform the following JSON into a java Object.
{
"Data":[
{
"AccountId":"2009852923",
"Currency":"EUR",
"Nickname":"SA 01",
"Account":{
"SchemeName":"BBAN",
"Name":"SA 01",
"Identification":"2009852923"
},
"Servicer":{
"SchemeName":"BICFI",
"Identification":"FNBSZAJJ"
}
},
{
"AccountId":"1028232942",
"Currency":"EUR",
"Nickname":"FNBCREDIT",
"Account":{
"SchemeName":"BBAN",
"Name":"FNBCREDIT",
"Identification":"1028232942"
},
"Servicer":{
"SchemeName":"BICFI",
"Identification":"FNBSZAJJ"
}
}
],
"Links":{
"self":"http://localhost:3000/api/open-banking/accounts/1009427721/transactions"
},
"Meta":{
"total-pages":1
}
}
Using the following DTO (for brevity, the referenced classes haven't been posted).
public class TransactionDTO {
private Data[] data;
private Links links;
private Meta meta;
public Data[] getData () { return data; }
public void setData (Data[] data) { this.data = data; }
public Links getLinks () { return links; }
public void setLinks (Links links) { this.links = links; }
public Meta getMeta () { return meta; }
public void setMeta (Meta meta) { this.meta = meta; }
}
The code to transform the DTO to a Java object being:
private TransactionDTO marshall(String accountTransactionsJSON) {
ObjectMapper objectMapper = new ObjectMapper();
TransactionDTO transactionDTO = null;
try {
transactionDTO = objectMapper.readValue(accountTransactionsJSON, TransactionDTO.class);
} catch (IOException e) {
e.printStackTrace();
}
return transactionDTO;
}
I'm getting this error:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Data" (class xxx.dto.TransactionDTO), not marked as ignorable (3 known properties: "links", "data", "meta"])
at [Source: java.io.StringReader@48f43b70; line: 2, column: 11] (through reference chain: xxx.dto.TransactionDTO["Data"])
I tried different approach to solve this issue such as:
objectMapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
As well as:
@JsonRootName(value = "data")
But I either get the same problem, or no problems, but the TransactionDTO
containing null
values only.
I guess the problem is the Data
field, but I don't know how to fix this problem (the solutions here don't work for me neither).
Questions
Upvotes: 9
Views: 40645
Reputation: 763
I got this error as I did not intend to map all the JSON fields to my POJO, but only a few. Consequently, it was asking me to mark them ignore. Following sample presents the idea:
@JsonIgnoreProperties(ignoreUnknown = true)
public class Book {
@JsonProperty("kind")
private String kind;
@JsonProperty("id")
private String id;
@JsonProperty("volumeInfo")
private BookInfo bookInfo;
@Override
public String toString() {
return "ClassPojo [kind = " + kind + ", id = " + id + ", bookInfo = " + bookInfo +"]";
}
On the other hand, my Json response carried out 10+ fields.
Upvotes: 4
Reputation: 1251
I solved a similar problem using this aproach
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
Upvotes: 9
Reputation: 10147
The problem is that your JSON property names (e.g. "Data"
)
don't match your Java property names (e.g. data
).
Besides @psmagin's answer there are two alternative options to fix it:
Keep your Java code unchanged.
And in the JSON contents change all keys (the strings left from the :
)
from first-uppercase to first-lowercase:
{
"data":[
{
"accountId":"2009852923",
"currency":"EUR",
"nickname":"SA 01",
"account":{
"schemeName":"BBAN",
"name":"SA 01",
"identification":"2009852923"
},
....
}
Keep the JSON contents unchanged.
And in your Java-code use @JsonProperty
annotations
to tell Jackson the corresponding JSON property-names of your Java properties:
public class TransactionDTO {
private @JsonProperty("Data") Data[] data;
private @JsonProperty("Links") Links links;
private @JsonProperty("Meta") Meta meta;
public Data[] getData () { return data; }
public void setData (Data[] data) { this.data = data; }
public Links getLinks () { return links; }
public void setLinks (Links links) { this.links = links; }
public Meta getMeta () { return meta; }
public void setMeta (Meta meta) { this.meta = meta; }
}
and in the same manner in your other Java classes
(Links
, Meta
, Data
, ...)
I would prefer the first option, because property names with first-lowercase are the established best practice in JSON and Java.
Upvotes: 5
Reputation: 1050
Jackson is case sensitive by default. Try this:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
Upvotes: 8