Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
543 views
in Technique[技术] by (71.8m points)

java - Why does Jackson 2 not recognize the first capital letter if the leading camel case word is only a single letter long?

I'm using Spring 4 MVC with Jackson 2 for my service. For one of the operations I have a request object that has an attribute where the leading camel case word this is only one letter in length:

private String aLogId;

This class has the appropriately named getters and setters:

public String getALogId() { return aLogId; }
public void setALogId(String aLogId) { this.aLogId = aLogId; }

However, when I attempt to post a request to this service using the corresponding JSON property:

{"aLogId":"This is a log id"}

I'm receiving a 500 response from the Spring framework saying the field is not recognized and my controller class is never called:

Could not read JSON: Unrecognized field "aLogId" (class

However, when I change the "L" to lower case, the request is deserialized as expected and my controller class is hit:

{"alogId":"This is a log id"}

Why does Jackson expect the "L" to be lower case when it is obviously the second word in the camel case convention for the attribute and intended to be in upper case? Is it because the first word is only a single letter long?

There are other attributes in the request object where the first word is more than one letter and those attributed don't face this same issue with the mismatch in case.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem you are seeing is due to the fact that Jackson uses Java Bean naming conventions to figure out the the Json properties in a Java class.

Here is a reference of the specific problem you see, the recommendation is not to capitalize either of the first two letters in your field. If you use an IDE like IntelliJ or eclipse and let the IDE generate the setters for you, you will notice the same "behavior" occurs, you will end up with the following methods:

public void setaLogId(String aLogId) {
    this.aLogId = aLogId;
}

public String getaLogId() {
    return aLogId;
}

Hence, when you change the "L" to lower case Jackson was able to figure it out the field you wanted to map.

Having said the above, you still have the alternative to use the "aLogId" field name and make Jackson work all you have to do is use the @JsonProperty annotation with the aLogId in it.

@JsonProperty("aLogId")
private String aLogId;

The following test code is to show how this will work:

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

public class Test {

    @JsonProperty("aLogId")
    private String aLogId;

    public void setaLogId(String aLogId) {
        this.aLogId = aLogId;
    }

    public String getaLogId() {
        return aLogId;
    }

    public static void main(String[] args) {

        ObjectMapper objectMapper = new ObjectMapper();

        Test test = new Test();

        test.setaLogId("anId");

        try {
            System.out.println("Serialization test: " + objectMapper.writeValueAsString(test));


            String json = "{"aLogId":"anotherId"}";

            Test anotherTest = objectMapper.readValue(json, Test.class);

            System.out.println("Deserialization test: " +anotherTest.getaLogId());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

The output of the test is:

Serialization test: {"aLogId":"anId"}

Deserialization test: anotherId


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...