在Kotlin中,Jackson反序列化错误与数据类 [英] In Kotlin, Jackson Deserialization error with data class

查看:622
本文介绍了在Kotlin中,Jackson反序列化错误与数据类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

不确定如何最好地解释这个问题,所以我提出了与java和kotlin相同的代码以更好地演示。

Not really sure how best to explain the problem so I whipped up the same code as both java and kotlin to better demonstration.

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

When I read JSON, it appears that it is forcing a data beans value to be NULL even though the parameter is not even part of the json to start with and the data bean defaults the value of the missing field. In java it works correctly never attempting to nullify the value that was never provided to start with. In Kotlin it seems to break because it tries to nullify a non-nullable field.

在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中(一切正常)

In Java (everything works fine)

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课堂上,它仍然以同样的方式出错。

Even if I make it a class instead of a data class in kotlin, it still errors out the same way.

我的问题是,我怎样才能让杰克逊反序列化与我的POJO一起在Kotlin中工作。预期的行为是,如果为不允许null的内容传入null /不正确的值,它应该中断。但是在上面没有尝试将ts字段更改为null的情况下,它应该像使用java那样使用默认值。

My question is, how can I get the Jackson deserialization to work in Kotlin with my POJO's. The expected behavior is that it "should" break if a null/incorrect value is passed in for something where null is not allowed. But in the scenario above where no attempt at all was made to change the ts field to a null, it should have used the default value like it does with java.

唯一让我头脑似乎工作的事情就是不要使用数据bean的概念并编写我的bean,如

The only thing that crosses my mind that seems to work is to not use the concept of the data bean at all and to write my beans like

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

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

But then my .equals does not work and it allows others downstream to manipulate the contents of the list and ts properties when I want them to be read-only.

推荐答案

使用 2.8.0 发布 jackson-kotlin-模块 它:


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

now supports using default values in constructor and creator methods

以下示例描述了该功能:

The following example depicts the feature:

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)

这篇关于在Kotlin中,Jackson反序列化错误与数据类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆