为什么SpringBoot可以在没有默认构造函数的情况下反序列化类?

pwuypxnk  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(630)

我想知道为什么SpringBoot可以反序列化jackson的objectmapper没有默认构造函数的类,但是当我在单元测试中手动使用objectmapper时,它不能反序列化(com.fasterxml.jackson.databind.exc.invaliddefinitionexception:cannot construct instance of `` (不存在像默认构造函数那样的创建者):无法从对象值反序列化(没有基于委托或属性的创建者))。
这是我的控制器:

@PostMapping("/precise")
  public Resp<List<MatchedOutLineResponseDTO>> getPreciseMatchedOutLine(
  @RequestBody List<MatchedOutLineRequestDTO> request)

这是我的观点:

@Getter
public class MatchedOutLineRequestDTO {

   private String uuid;
   private JSONObject outLineGeometry;

   public MatchedOutLineRequestDTO(String uuid, JSONObject outLineGeometry) {
     this.uuid = uuid;
     this.outLineGeometry = outLineGeometry;
   }
 }

有人能告诉我原因吗?

ccrfmcuu

ccrfmcuu1#

@h、 德菲森
json序列化(对象到json)
不需要无参数构造函数
只需要 Getter 要公开的属性的方法
json反序列化(json到对象)
需要无参数构造函数和setter方法
这是因为对象Map器首先使用noargs构造函数创建类,然后使用setter设置字段值。
考虑下面的代码示例

public class Test {
@Getter
static class Dummy {

    private String uuid;
    private Date date;
    private JSONObject jsonObject;

    public Dummy(String uuid, Date date, JSONObject jsonObject) {
        this.uuid = uuid;
        this.date = date;
        this.jsonObject = jsonObject;
    }
}

public static void main(String[] args) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();

    JSONObject jsonObject = new JSONObject();
    jsonObject.put("Name", "John Doe");
    jsonObject.put("Age", "Unknown");
    Dummy dummyObj = new Dummy(UUID.randomUUID().toString(), new Date(), jsonObject);

    String jsonStr = mapper.writeValueAsString(dummyObj);
    System.out.println("Serialized JSON = " + jsonStr);
}

}
如果您运行此代码,您将得到它的唯一序列化错误 No serializer found for class org.json.JSONObject 问题是 JSONObject 班级。
objectmapper示例的默认配置是仅访问公共字段或具有公共getter的属性。
因此,这就是序列化的问题 org.json.JSONObject 几乎没有解决办法
删除 JsonObject 并使用 Map 相反
通过添加以下命令,将对象Map器配置为访问私有字段 mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); 您将看到这样的输出 Serialized JSON = {"uuid":"15f37c75-9a82-476b-a725-90f3742d3de1","date":1607961986243,"jsonObject":{"map":{"Age":"Unknown","Name":"John Doe"}}} 最后一个选项是忽略失败的字段(如 JSONObject )并序列化其余字段。可以这样配置对象Map器 mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 如果这样做,您将看到如下输出 Serialized JSON = {"uuid":"82808d07-47eb-4f56-85ff-7a788158bbb5","date":1607962486862,"jsonObject":{}}

相关问题