@JsonProperty 存在但返回 null

问题描述

我有一个使用 Java 11 的带注释的 Fasterxml 类,即使我可以看到源 JSON 中的数据,它也会为其中一个属性返回 null。此注释不再适用于 jackson:2.12.0 是否有任何原因?

有问题的属性在源代码中大写,因此在注释中也大写。

源 JSON

{
    "stringOne": "hello","stringTwo": "world","floatOne": 0.0,"NUM": 15   <-- always returns null
}

日志声明

TestJson{stringOne='hello',stringTwo='world',floatOne=0.0,NUM=null}

课程

   import com.fasterxml.jackson.annotation.JsonProperty;

import java.io.Serializable;

@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
public class TestJson implements Serializable{

    protected String stringOne;
    protected String stringTwo;
    protected Float floatOne;
    protected Integer NUM;

    @JsonProperty("stringOne")
    public String getStringOne() {
        return stringOne;
    }

    public void setStringOne(String stringOne) {
        this.stringOne = stringOne;
    }

    @JsonProperty("stringTwo")
    public String getStringTwo() {
        return stringTwo;
    }

    public void setStringTwo(String stringTwo) {
        this.stringTwo = stringTwo;
    }

    @JsonProperty("floatOne")
    public Float getFloat() {
        return floatOne;
    }

    public void setFloat(Float floatOne) {
        this.floatOne = floatOne;
    }

//////// Returns null for every 'NUM' property
    @JsonProperty("NUM")
    public Integer getNum() {
        return NUM;
    }
    
    @JsonProperty("NUM")
    public void setNum(Integer NUM) {
        this.NUM= NUM;
    }

Override
    public String toString() {
        return "TestJson{" +
                "stringOne='" + stringOne + '\'' +
                ",stringTwo='" + stringTwo + '\'' +
                ",floatOne=" + floatOne +
                ",NUM=" + NUM+
                '}';
    }
   
}

编辑

将用于检索/序列化数据的请求添加TestJson 对象

        ClientResponse<TestJson> response = null;
        TestJson testJson = null;
        logger.info(encodeForLog("apiUrl.getPath: " + apiUrl.getPath()));
        logger.info("proxy:" + proxy);

        try {
            response = proxy.getData(apiUrl.getPath());

            if (response.getStatus() == Response.Status.OK.getStatusCode()) {
                testJson = response.getEntity();
                
                return testJson;
            } else {
                throw new FailedException("HTTP failure");
            }
        }
        finally {
            if (response != null) {
                response.releaseConnection();
            }
        }

解决方法

在 setter 方法上设置 @JsonProperty。

@JsonProperty("NUM")
public Integer getNum() {
    return num;
}

@JsonProperty("NUM")
public void setNum(Integer num) {
    this.num = num;
}

可用于将非静态方法定义为 逻辑属性的“setter”或“getter”(取决于其签名),或用作逻辑属性(序列化、反序列化)的非静态对象字段。

https://fasterxml.github.io/jackson-annotations/javadoc/2.8/com/fasterxml/jackson/annotation/JsonProperty.html

Jackson 版本无关紧要:

https://fasterxml.github.io/jackson-annotations/javadoc/2.12/com/fasterxml/jackson/annotation/JsonProperty.html

用这个类测试(Jackson 2.11.4):

@JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)
public class TestJson implements Serializable {

    protected String stringOne;
    protected String stringTwo;
    protected Float floatOne;
    protected Integer num;

    @JsonProperty("stringOne")
    public String getStringOne() {
        return stringOne;
    }

    public void setStringOne(String stringOne) {
        this.stringOne = stringOne;
    }

    @JsonProperty("stringTwo")
    public String getStringTwo() {
        return stringTwo;
    }

    public void setStringTwo(String stringTwo) {
        this.stringTwo = stringTwo;
    }

    @JsonProperty("floatOne")
    public Float getFloat() {
        return floatOne;
    }

    public void setFloat(Float floatOne) {
        this.floatOne = floatOne;
    }

    //////// Returns null for every 'NUM' property
    @JsonProperty("NUM")
    public Integer getNum() {
        return num;
    }

    @JsonProperty("NUM")
    public void setNum(Integer num) {
        this.num= num;
    }

    @Override
    public String toString() {
        return "TestJson{" +
                "stringOne='" + stringOne + '\'' +
                ",stringTwo='" + stringTwo + '\'' +
                ",floatOne=" + floatOne +
                ",NUM=" + num+
                '}';
    }

}

输出:

enter image description here

以及更好的 TestJson 解决方案:

public class TestJson implements Serializable {

    protected String stringOne;
    protected String stringTwo;
    protected Float floatOne;
    protected Integer num;

    @JsonCreator
    public TestJson(@JsonProperty("stringOne") String stringOne,@JsonProperty("stringTwo") String stringTwo,@JsonProperty("floatOne") Float floatOne,@JsonProperty("NUM") Integer num) {
        this.stringOne = stringOne;
        this.stringTwo = stringTwo;
        this.floatOne = floatOne;
        this.num = num;
    }

    public String getStringOne() {
        return stringOne;
    }

    public void setStringOne(String stringOne) {
        this.stringOne = stringOne;
    }

    public String getStringTwo() {
        return stringTwo;
    }

    public void setStringTwo(String stringTwo) {
        this.stringTwo = stringTwo;
    }

    public Float getFloat() {
        return floatOne;
    }

    public void setFloat(Float floatOne) {
        this.floatOne = floatOne;
    }

    public Integer getNum() {
        return num;
    }

    public void setNum(Integer num) {
        this.num= num;
    }

    @Override
    public String toString() {
        return "TestJson{" +
                "stringOne='" + stringOne + '\'' +
                ",NUM=" + num+
                '}';
    }

}