spring 尽管有公共setter,Jackson仍无法反序列化对象

jvidinwx  于 2023-06-21  发布在  Spring
关注(0)|答案(1)|浏览(116)

我有实体:

DummyEntity.java

package com.example.demo.DummyObject;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.*;

import java.io.IOException;
import java.util.Date;
import java.util.Map;

/**
 * An entity containing analyzed data
 *
 * @author Thorvas
 */
@Entity
@Table(name="DUMMY_ENTITY")
public class DummyEntity {

    public DummyEntity() {

    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name = "name")
    private String name;

    @ElementCollection
    private Map<String, Integer> population;

    @Column(name = "estimation")
    private int estimation;

    @Column(name = "last_updated")
    @Temporal(TemporalType.DATE)
    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonProperty("last_updated")
    private Date lastUpdated;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Map<String, Integer> getPopulation() {
        return population;
    }

    public void setPopulation(Map<String, Integer> population) {
        this.population = population;
    }

    public int getEstimation() {
        return estimation;
    }

    public void setEstimation(int estimation) {
        this.estimation = estimation;
    }

    public Date getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    public int getId() {
        return id;
    }

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

我在POST端点上发布以下数据:

{
  "name": "Powiat ząbkowicki",
  "population": {
    "2013": 67875,
    "2014": 67458,
    "2015": 66971,
    "2016": 66527,
    "2017": 66009,
    "2018": 65428,
    "2019": 64802,
    "2020": 62561,
    "2021": 61846,
    "2022": 61087
  },
  "estimation": 0,
  "last_updated": "2023-06-09"
}

当我发布它时,我得到一个错误:

no String-argument constructor/factory method to deserialize from String value ('{"name": "Powiat ząbkowicki", "population": {"2013": 67875, "2014": 67458, "2015": 66971, "2016": 66527, "2017": 66009, "2018": 65428, "2019": 64802, "2020": 62561, "2021": 61846, "2022": 61087}, "estimation": 0, "last_updated": "2023-06-09"}')]

为什么?我所有的setter和getter都是public的。由于某些原因Jackson不能正确地反序列化我的对象,并希望构造函数具有String值。当我加上这个,问题就解决了:

public DummyEntity(String json) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        DummyEntity dummyEntity = objectMapper.readValue(json, DummyEntity.class);
        this.name = dummyEntity.name;
        this.population = dummyEntity.population;
        this.estimation = dummyEntity.estimation;
        this.lastUpdated = dummyEntity.lastUpdated;
    }

但是为什么我们需要这个构造函数呢?Jackson不能自己做吗

cl25kdpy

cl25kdpy1#

no要从String value('{“name”:“Powiat ząbkowicki”,...
错误消息解释了您的应用程序收到了一个String对象,其中包含您要转换为DummyEntity对象的json,而不是DummyEntity对象的json表示;你必须将字符串值转换为JsonNode节点,并使用JsonNode#asText方法将其关联值读取为有效的String表示:

@Data
public class DummyEntity {
    private String name;
}

// deserializing json "{\"name\": \"Powiat ząbkowicki\"}"
String content = mapper.readTree(json).asText();
DummyEntity dummyEntity = mapper.readValue(content, DummyEntity.class);
//ok, it prints DummyEntity(name=Powiat ząbkowicki)
System.out.println(dummyEntity);

相关问题