com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

时间:2024-03-16 14:59:02

问题

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

详细问题

笔者服务端实体类的getset方法由Lombok@Getter@Setter注解生成,客户端实体类的getset方法由于对Lombok@Getter@Setter注解支持不够友好,故直接由IDEA生成。
笔者服务端实体类

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Agricultural {
    private int id;
    private int year;
    private int doy;
    private double allSkySfcSwDwn;
    private double gWetRoot;
    private double latitude;
    private double longitude;
    private double wS2M;
    private String sunshineTime;
}

笔者客户端实体类

public class Agricultural {

    private int id;
    private int year;
    private int doy;
    private double allSkySfcSwDwn;
    private double gWetRoot;
    private double latitude;
    private double longitude;
    private double wS2M;
    private String sunshineTime;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getDoy() {
        return doy;
    }

    public void setDoy(int doy) {
        this.doy = doy;
    }

    public double getAllSkySfcSwDwn() {
        return allSkySfcSwDwn;
    }

    public void setAllSkySfcSwDwn(double allSkySfcSwDwn) {
        this.allSkySfcSwDwn = allSkySfcSwDwn;
    }

    public double getgWetRoot() {
        return gWetRoot;
    }

    public void setgWetRoot(double gWetRoot) {
        this.gWetRoot = gWetRoot;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    public double getwS2M() {
        return wS2M;
    }

    public void setwS2M(double wS2M) {
        this.wS2M = wS2M;
    }

    public String getSunshineTime() {
        return sunshineTime;
    }

    public void setSunshineTime(String sunshineTime) {
        this.sunshineTime = sunshineTime;
    }

    @Override
    public String toString() {
        return "Agricultural{" +
                "id=" + id +
                ", year=" + year +
                ", doy=" + doy +
                ", allSkySfcSwDwn=" + allSkySfcSwDwn +
                ", gWetRoot=" + gWetRoot +
                ", latitude=" + latitude +
                ", longitude=" + longitude +
                ", wS2M=" + wS2M +
                ", sunshineTime='" + sunshineTime + '\'' +
                '}';
    }
}

客户端发送请求,服务端接收请求处理数据反馈客户端,客户端报错

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ws2M" (class com.example.assistingagriculture.entity.Agricultural), not marked as ignorable (9 known properties: "gWetRoot", "allSkySfcSwDwn", "id", "latitude", "year", "doy", "longitude", "wS2M", "sunshineTime"])
 at [Source: (String)"[{"id":14316,"year":2023,"doy":70,"allSkySfcSwDwn":14.83,"latitude":36.97,"longitude":100.9,"sunshineTime":"7:19:28","ws2M":3.37,"gwetRoot":0.59},{"id":14317,"year":2023,"doy":71,"allSkySfcSwDwn":18.08,"latitude":36.97,"longitude":100.9,"sunshineTime":"7:20:23","ws2M":4.13,"gwetRoot":0.59},{"id":14318,"year":2023,"doy":72,"allSkySfcSwDwn":20.07,"latitude":36.97,"longitude":100.9,"sunshineTime":"7:21:18","ws2M":4.47,"gwetRoot":0.59},{"id":14319,"year":2023,"doy":73,"allSkySfcSwDwn":13.8,"latitude"[truncated 20434 chars]; line: 1, column: 129] (through reference chain: java.util.ArrayList[0]->com.example.assistingagriculture.entity.Agricultural["ws2M"])

解决方案

在服务端的实体类属性上使用 @JsonProperty 注解来明确指定 JSON 中的字段名。
即修改为

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Agricultural {
    private int id;
    private int year;
    private int doy;
    private double allSkySfcSwDwn;
    @JsonProperty("gWetRoot")
    private double gWetRoot;
    private double latitude;
    private double longitude;
    @JsonProperty("wS2M")
    private double wS2M;
    private String sunshineTime;
}

产生原因

Jackson 在反序列化 JSON 时,默认遵循 JavaBean 的命名规范来识别 JSON 属性与 Java 属性之间的映射关系。当 Java 属性名的首字母小写,第二个字母大写时,按照 JavaBean 规范,期望的 getter/setter 方法名称与实际生成的名称不符,导致 Jackson 无法正确映射 JSON 属性到 Java 属性。这就是客户端在反序列化包含属性名首字母小写且第二个字母大写的 JSON 数据时出错的原因。

解决原因

为了解决这个问题,采用了明确指定 JSON 字段名的方式。在服务端实体类的属性上使用 @JsonProperty 注解,显式地指定了 JSON 中的字段名,确保无论客户端如何生成 getter 和 setter 方法,Jackson 在序列化和反序列化时都能正确识别字段。

参考文献

产生原因与解释原因部分 部分内容参考chatgpt

原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈
请添加图片描述