1

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;
 }
}
Steven Matthews
  • 9,705
  • 45
  • 126
  • 232
  • 1
    Does this answer your question? [Jackson JSON field mapping capitalization?](https://stackoverflow.com/questions/15303110/jackson-json-field-mapping-capitalization) – kasptom Oct 28 '20 at 17:43
  • It's definitely setting me on the right path, but when I change Symbol to symbol in my Stock class variable, I am still getting: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Symbol" – Steven Matthews Oct 28 '20 at 17:54

2 Answers2

2

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 named symbol 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

kasptom
  • 2,363
  • 2
  • 16
  • 20
0

You can also configure your ObjectMapper to check only fields and ignore getters:

JsonMapper mapper = JsonMapper.builder()
        .visibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
        .visibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
        .build();
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146