I am trying to take some JSON that looks like this (from AlphaVantage):
{
"Symbol": "IBM",
"AssetType": "Common Stock",
"Name": "International Business Machines Corporation",
... more properties
}
And parse it using Jackson (& Ebeans):
ObjectMapper objectMapper = new ObjectMapper();
String json = response.body().string();
Stock stock = objectMapper.readValue(json, Stock.class);
stock.save();
My Stock class looks like this:
@Entity
@Table(name = "stock")
public class Stock extends Model {
@Id
private Long id;
private String Symbol;
private String AssetType;
private String Name;
... other properties
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getSymbol() {
return this.Symbol;
}
public void setSymbol(String Symbol) {
this.Symbol = Symbol;
}
... other setters/getters
}
Instead I am getting the following error:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Symbol" (class com.myprojectname.Stock), not marked as ignorable (60 known properties: "ebitda", "sharesOutstanding", "bookValue", ....more fields
Why is Jackson having a problem connecting to my Stock class? How do I connect Symbol from the JSON into Symbol in the Stock class?
EDIT: I get the same error message if I change symbol to lowercase:
@Entity
@Table(name = "stock")
public class Stock extends Model {
@Id
private Long id;
private String symbol;
public String getSymbol() {
return this.symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
}
Changing the name of the property from Symbol
to symbol
won't help since we still have the "Symbol"
in the json file.
You can try to use the @JsonProperty
annotation like in the example. For the "Symbol"
json field it can look like this:
//...
private String Symbol;
@JsonProperty("Symbol")
public String getSymbol() {
return this.Symbol;
}
@JsonProperty("Symbol")
public void setSymbol(String symbol) {
this.Symbol = symbol;
}
// ...
This approach should also work for other fields which differ from the json counterpart by the uppercase / lowercase letter.
edit: Just like in the answer from the question linked in my comment above - paraphrasing it:
Since your setter method is named
setSymbol()
Jackson assumes the variable is namedsymbol
because of the Java naming conventions (variables should start with lower case letters).
edit(2): Other option would be leveraging the object mapper configuration. So instead of the annotations approach you could use the approach from here and make the mapper case insensitive:
objectMapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
Other property I find useful is:
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
described in the Baeldung's article linked above