I am using Jackson in Spring to serialize my class to JSON. When I serialize a class like the example below, Jackson is changing the names of certain fields from Camel Case to lower case. I know I can work around this by creating custom (de)serializers, yet I am hoping to turn this off globally. Perhaps by setting a property in application.properties.
Per the default Jackson naming strategy, this is not supposed to happen:
In absence of a registered custom strategy, default Java property naming strategy is used, which leaves field names as is...
class Foo {
private final String firstName;
private final String aName;
private final String name;
private final String abName;
Foo(final String firstName, final String aName, final String name, final String abName) {
this.firstName = firstName;
this.aName = aName;
this.name = name;
this.abName = abName;
}
// Getters here
}
public static void main(String[] args) {
final ObjectMapper mapper = new ObjectMapper();
final Foo foo = new Foo("first", "a", "name", "ab");
final String jsonInString = mapper.writeValueAsString(foo);
System.out.println(jsonInString);
}
Expected:
{"firstName":"first","name":"name","abName":"ab","aName":"a"}
Actual:
{"firstName":"first","name":"name","abName":"ab","aname":"a"}
EDIT:
Narrowed the problem down to interpretation of the getters. Starting to look like a bug in Jackson.
class Foo {
private final String aName;
Foo(final String aName) {
this.aName = aName;
}
public String getaName() {
return this.aName;
}
}
Serializes to {"aName":"a"}
However,
class Foo {
private final String aName;
Foo(final String aName) {
this.aName = aName;
}
public String getAName() {
return this.aName;
}
}
Serializes to {"aname":"a"}
The problem here is more about JavaBeans(TM) Specification. According to the spec (page 58)
However to support the occasional use of all upper-case names, we check if the first two characters of the name are both upper case and if so leave it alone
“FooBah” becomes “fooBah”
“Z” becomes “z”
“URL” becomes “URL”
And you have an edge case with aName
field . Because if the getter looks like AName()
, then when you convert back from this getter you should look for AName
field according to the specification. Here is additional info explanation
So to fix this, you can use a proper getter(getaName()
) or @JsonProperty("aName")
annotation above field/getter
Here is similar question
Although I'm not sure why Jackson reads getAName
to aname
, it's possible to force a Jackson to use a certain name with @JsonProperty("AName")
. For example:
class Foo {
private final String aName;
Foo(final String aName) {
this.aName = aName;
}
@JsonProperty("AName")
public String getAName() {
return this.aName;
}
}
(Got this solution from this closely related question.)
You can also use PropertyNamingStrategy option in Objectmapper.
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.UPPER_CAMEL_CASE)
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