Java – why doesn’t Jackson 2 recognize the first capital letter if the leading camel case word is only one letter long?

I am using spring 4 MVC with Jackson 2 my service For one of the operations, I have a request object with an attribute, in which the main word is just the length of one letter:

private String aLogId;

This class has appropriately named getters and setters:

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

However, when I try to publish a request to the service using the corresponding JSON attribute:

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

I received 500 responses from the spring framework, indicating that the field is not recognized, and my controller class is never called:

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

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

Why does Jackson want "L" to be lowercase when it is clearly the second word of this attribute's camel case convention, intended to be uppercase? Is it because the first word is only one letter long?

There are other attributes in the request object, in which the first word is more than one letter, and these attributes do not belong to the same problem that does not match

Solution

The problem you see is that Jackson uses the Java Bean naming convention to determine the JSON attribute in the Java class

This is the reference of the specific problem you see. It is recommended not to capitalize the first two letters in the field If you use an IDE like IntelliJ or eclipse and let the IDE generate setters for you, you will notice that the same "behavior" occurs, and you will eventually get the following methods:

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

public String getaLogId() {
    return aLogId;
}

Therefore, when you change "L" to lowercase, Jackson can display the field you want to map

After that, you can still choose to use the "alogid" field name, and all you need to do to make Jackson work is to use the @ jsonproperty annotation with the alogid in it

@JsonProperty("aLogId")
private String aLogId;

The following test code shows how to run:

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: otherid

I hope it helps,

Jose Louis

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>