当前位置: 首页 > 知识库问答 >
问题:

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

施昊然
2023-03-14

我想知道为什么Spring boot可以反序列化没有默认构造函数的类由Jackson的ObjectMapper,但是当我在单元测试中手动使用ObjectMapper时,它不能反序列化(com.fasterxml.jackson.databind.exc.Invalid定义异常:不能构造实例的xxx(没有创建者,像默认构造函数,存在):不能反序列化从对象值(没有基于委托或属性的创建者))。

这是我的控制器:

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

这是我的pojo:

@Getter
public class MatchedOutLineRequestDTO {

   private String uuid;
   private JSONObject outLineGeometry;

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

谁能告诉我原因吗?

共有1个答案

文嘉禧
2023-03-14
  • Json序列化(对象到Json)
  • 需要无参数构造函数和setter,因为对象映射器首先使用无参数构造函数创建类,然后使用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);
    }
}

如果运行此代码,您将得到的唯一序列化错误是未找到类org的序列化程序。json。J主题

问题是JSONObject类的序列化。

ObjectMapper实例的默认配置是仅访问公共字段或具有公共getter的属性。

因此,这是org序列化中的问题。json。JSONObject。

几乎没有解决办法

>

  • 删除JsonObject,使用地图。

    通过添加以下内容来配置您的对象映射器以访问私有字段:

    mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
    

    您将看到如下输出

    {
        "uuid": "15f37c75-9a82-476b-a725-90f3742d3de1",
        "date": 1607961986243,
        "jsonObject": {
            "map": {
                "Age": "Unknown",
                "Name": "John Doe"
            }
        }
    }
    

    最后一个选项是忽略失败的字段(如JSONObject)并序列化其余字段。可以通过如下方式配置对象映射器来实现这一点:

    mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    

    如果您这样做,您将看到如下所示的输出:

    {
        "uuid": "82808d07-47eb-4f56-85ff-7a788158bbb5",
        "date": 1607962486862,
        "jsonObject": {}
    }
    

  •  类似资料:
    • 问题内容: 我想使用com.fasterxml.jackson.databind.ObjectMapper序列化和反序列化不可变对象。 不可变类如下所示(只有3个内部属性,获取器和构造函数): 但是,当我运行此单元测试时: 我得到这个例外: 这个异常要求我创建一个默认的构造函数,但这是一个不可变的对象,所以我不想拥有它。它将如何设置内部属性?这会完全混淆API的用户。 所以我的问题是: 我可以在没

    • 我有一个类,它有一个默认构造函数,还有一个重载构造函数,它接受一组参数。这些参数与对象上的字段匹配,并在构造时指定。此时,我需要用于其他目的的默认构造函数,因此如果可以的话,我希望保留它。 我的问题:如果我删除默认的构造函数并传递JSON字符串,对象反序列化正确,并传递构造函数参数没有任何问题。我最终以我所期望的方式找回填充的对象。但是,一旦我将默认构造函数添加到对象中,当我调用

    • 我使用了Spring Boot 1.4.3。release和bean能够从JSON反序列化这样的对象。 升级到Spring Boot 2.0.0.M7后,我收到以下异常: 那么,为什么它在Spring Boot1.4.3中工作,而在Spring Boot2中失败呢?是否可以将bean配置为与旧版本相同的行为方式?

    • 当我们的团队处理关于C代码中POD的单元化成员的valgrind警告时,我想到了这个有趣的答案: https://stackoverflow.com/a/5914697/629530 重申要点,考虑C中的以下POD结构: 构造C类型对象的以下调用调用默认构造函数,成员使用该默认构造函数初始化(再次复制Martin York答案中的代码和注释): 有道理。Martin York继续指出,使用以下声明

    • 活体->动物->NPC->人->孩子 Live、Animal和NPC不实现Serializable。我不能改变这三门课。Person和Child确实实现了Serializable。人和生活也是抽象的类。我可以很好地序列化一个人(他是一个孩子)并发送它,但是当我尝试反序列化一个人(他是一个孩子)时,我在Child上得到一个InvalidClassException(无效构造函数),表示“no val

    • 问题内容: 我在使用Jackson来反序列化JSON字符串时遇到问题(但是我没有问题将对象序列化为JSON)。 下面,我介绍我使用的类。当我接收到JSON字符串(已在其他地方进行序列化并通过Web服务检索的ProtocolContainer)并想反序列化时,就会出现问题: JSON字符串: {“ DataPacketJSONString”:null,“ DataPacketType”:“ MyPa