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

在科特林中,杰克逊数据类的反序列化错误

山疏珂
2023-03-14

不知道如何最好地解释这个问题,所以我使用了与java和kotlin相同的代码来更好地演示。

当我阅读JSON时,它似乎强制数据bean值为NULL,即使该参数甚至不是JSON的一部分,并且数据bean默认为缺失字段的值。在java中,它工作正常,从不试图使一开始从未提供的值无效。在Kotlin中,它似乎中断了,因为它试图使不可为空的字段无效。

静态编程语言

data class Pojo(val name: String, val age: Int, val list: List<String> = emptyList(), val ts: Date = Date())

private val mapper: ObjectMapper = ObjectMapper().registerModule(KotlinModule())
    .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)

fun main(args: Array<String>) {
    mapper.readValue("""{"name": "John Doe", "list": ["yellow", "green"], "age": 42}""", Pojo::class.java)
}

这将引发

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method Pojo.<init>, parameter ts

在Java中(一切正常)

public class Transform {
  private static ObjectMapper mapper = new ObjectMapper()
        .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

  public static class Pojo {
    private String name;
    private int age;
    private List<String> list;
    private Date ts = new Date();
    <getters and setters for all>
  }

  public static void main(String[] args) throws IOException {
    String json = "{\"name\": \"John Doe\", \"list\": [\"yellow\", \"green\"], \"age\": 42}";
    Pojo p = mapper.readValue(json, Pojo.class);
    System.out.printf("Bean: name=%s, age=%s, list=%s, ts=%s\n", p.name, p.age, p.list, p.ts);
  }
}

即使我在kotlin中将它变成一个类而不是数据类,它仍然会以同样的方式出错。

我的问题是,我如何才能让杰克逊反序列化与我的POJO一起在科特林工作。预期的行为是,如果为不允许为null的内容传递了null/不正确的值,那么它“应该”中断。但在上面的场景中,根本没有尝试将ts字段更改为null,它应该像在java中那样使用默认值。

我脑海中唯一似乎有效的就是根本不使用数据豆的概念,而是把我的豆子写成

class Pojo(val name: String, val age: Int) {
    var list: List<String> = emptyList()
    var ts: Date = Date()
}

但是我的. equals不起作用,它允许下游的其他人在我希望列表和ts属性为只读时操作它们的内容。

共有2个答案

勾岳
2023-03-14

我认为您的一个传入属性为空,所以您需要将< code >?在jsonProperty之后,可以是null(在您的情况下,这是您的日期字段)。您还可以使用原始字符串数据类型进行带有三重引号的测试< code未转义字符串" " " ,因此应该是这样的< code>val ts: Date?在您的数据类内部。你不需要重新声明类型。所以最终答案是:< code >数据类Pojo(val name: String,val age: Int,val list: List

仇高韵
2023-03-14

随着2.8.0发布的jackson-kotlin-dule它:

现在支持在构造函数和创建者方法中使用默认值

以下示例描述了该功能

data class Question(val title: String = "Is programming hard?", val answer: String)

val q = mapper.readValue<Question>("""{"answer": "Sure it can be"}""")
println(q) //-> Question(title=Is programming hard?, answer=Sure it can be)
 类似资料:
  • 问题内容: 我的问题很简单:我有以下简单的类: 我正在尝试处理以下JSON: 显然,这里存在一个问题(“ blah”无法解析为int) 以前,Jackson抛出类似org.codehaus.jackson.map.JsonMappingException的内容:无法从字符串值’blah’构造java.lang.Integer的实例:不是有效的Integer值 我同意这一点,但是我想在某个地方注册一

  • 我正在调用一个返回JSON的endpoint,它看起来像这样(在Postman中): 此请求返回的Content-Type头是(与通常的 类来自外部库(编写这个endpoint的人)。无论如何,当我试图通过< code > rest template . exchange()调用这个endpoint时,Jackson都无法将这个JSON反序列化为一个有效的< code>Result类。我正在这样做

  • 我正在尝试使用杰克逊将 JSON 对象反序列化为 Java 对象。json 是由另一位开发人员使用 jackson 库本身创建的,并提供给我。对象图有一个类型为guava的不可变映射的变量,它是一个抽象类。因此,当我尝试反序列化时,杰克逊会给我抛出以下异常。我不是 myJava 类的所有者,因此无法对其进行任何更改,例如通过编写自定义反序列化程序来更改类型或添加注释。 org.codehaus.j

  • 问题内容: 我有一个叫做抽象类,然后两个是实现,和。我遇到的问题是,当我将a的其余端点调用到数据库中时,理想情况下,我希望它像将实例传递给REST端点的位置一样。如果不是用一个以上的实现来抽象,那就没问题了,但是由于我有2个,所以我得到了一个错误。 “问题:抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么被其他类型信息实例化” 在找到解决方案之后,我找到了一个SO答案,说我可以使用类

  • 我明白它无法从嵌套JSON反序列化字符串。我解决这个问题的一个方法是通过编写自定义映射器 但是只要pojo中有变化,这就需要修改映射器,添加/删除字段。Mixin工作时没有任何变化,我该如何更新我的Mixin来处理objectId呢?

  • 我想用scala中的jackson反序列化json json_结构: {“type”:“struct”,“fields”:[{“name”:“code_role”,“type”:“string”,“nullable”:true,“metadata”:{“HIVE_type_string”:“string”},{“name”:“libelle_role”,“type”:“string”,“nulla