Jackson seems to have a problem when the second letter of a field name is capitalized.
Take a map of values:
aaBoolean, true // works
aBoolean, false // fails
anInt, 0 // works
aString, "a" // fails
I used Jackson's ObjectMapper.convertValue(map)
to create a Java object. Here's a snippet of Java code:
private boolean aaBoolean; // GOOD
public boolean getAaBoolean() { return aaBoolean; }
public void setAaBoolean(boolean value) { this.aaBoolean=value;}
private boolean aBoolean; // FAILS!!! Jackson "Unrecognized field"
public boolean getABoolean() { return aBoolean; }
public void setABoolean(boolean value) { this.aBoolean=value;}
I get an error message with all 18 fields. Note the camel case fails when the capital is the second letter:
Unrecognized field "aBoolean" (class Test), not marked as ignorable
(18 known properties: "anInt", "anullableBoolean", "aboolean", "aaBoolean",
"lastModifiedDate", "adate", "anullableDate", "astring", "anullableString",
"createdDate", "anullableFloat", "id", "along", "anullableLong", "createdBy",
"anullableInt", "lastModifiedBy", "afloat"])
If I change aBoolean
to aaBoolean
, that passes and Jackson fails on aString
.
Per other Stack Overflow posts, I've verified that the field name and getter/setter match (aBoolean
is getABoolean()
and aaBoolean
is getAaBoolean()
).
If it matters, here's how the ObjectMapper
was created:
ObjectMapper mapper = new ObjectMapper();
mapper.setTimeZone(TimeZone.getTimeZone("CST"));
I can post the full code but I think the above is enough.
I can modify my variable names to get around this, but now I'm curious - is this a bug or am I missing something about how Jackson handles name conversion?
It looks like the default Jackson behavior through v2.9 is to lowercase any leading upper case getter/setter methods. So "getURLtoServer" becomes "urltoServer".
Jackson source code executing this here: https://github.com/FasterXML/jackson-databind/blob/2.9/src/main/java/com/fasterxml/jackson/databind/util/BeanUtil.java#L246
However, the JavaBean spec says to not change any casing if the first two characters are uppercase. So the JavaBean of "getURLtoServer" would be "URLtoServer".
Jackson introduced MapperFeature.USE_STD_BEAN_NAMING as an option to enforce this part of the JavaBean spec. However, it looks like that's being removed in v3.x when it becomes the default behavior: https://github.com/FasterXML/jackson-databind/issues/1772
So for your case, it looks like you can either have the JSON string "aboolean" without using USE_STD_BEAN_NAMING, or else you can have the JSON string "ABoolean" with using USE_STD_BEAN_NAMING.
The other option is to manually specify what you want:
@JsonProperty("aBoolean")
public boolean getABoolean() { return aBoolean; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With