在顶级地图上使用@JacksonInject和@JsonCreator

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在顶级地图上使用@JacksonInject和@JsonCreator相关的知识,希望对你有一定的参考价值。

使用Jackson json库,可以通过使用@JsonCreator反序列化对象,并给出表示输入json的“顶级”映射,如下所示:

class MyClass {
    final int field;

    @JsonCreator
    public MyClass(Map<String, Object> map) {
        this.field = (int) map.get("theInt");
    }
}

甚至是静态工厂方法:

class MyClass {
    final int field;

    public MyClass(int theInt) {
        this.field = theInt;
    }

    @JsonCreator
    static MyClass create(Map<String, Object> map) {
        return new MyClass((int) map.get("theInt"));
    }
}

前面的示例可以处理以下类型的json输入:

{
    "key1":"value1",
    "key2":"value2",
    "key3":"value3"
}

这在我的情况下特别有用,因为我想反序列化一个我不知道的json结构。通过访问我称之为“顶级地图”的内容,可以简化操作。

我想以这种方式反序列化我的对象,因为它也允许创建不可变对象,而不是使用不允许这个的@JsonAnySetter,以及我不能使用的@JsonProperty因为我事先不知道属性名称较早前提过。

然后更进一步,我想在我的工厂方法中注入一些配置,杰克逊通过使用@JacksonInject和在withInjectableValues(InjectableValues)上调用ObjectMapper来实现这一点。

这最终是我想要使用的代码类型:

class MyClass {
    final MyField[] myFields;

    public MyClass(MyField... myFields) {
        this.myFields = myFields;
    }

    @JsonCreator
    static MyClass create(@JacksonInject("conf") Conf conf, Map<String, Object> map) {
        MyFields[] myFields;
        // initialize myFields (or any other object) based on the content of map
        // and also make use of the inject conf
        return new MyClass(myFields);
    }
}

不幸的是,杰克逊抛出以下类型的例外:

  • 在构造函数上尝试这个技巧时

JsonMappingException: Argument #1 of constructor [constructor for MyClass, annotations: {JsonCreator=@JsonCreator()}] has no property name annotation; must have name when multiple-paramater constructor annotated as Creator

  • 在工厂方法上尝试这个技巧时

JsonMappingException: Argument #1 of factory method [method create, annotations: {JsonCreator=@JsonCreator()}] has no property name annotation; must have when multiple-paramater static method annotated as Creator

有谁知道我怎么能解决这个问题?

总结要求,我需要:

  • 访问顶级地图(事先不知道json属性名称)
  • 创建一个不可变对象(所以不能使用@JsonAnySetter
  • @JsonCreator装饰构造函数或工厂方法注入一些conf

我无法更改json输入格式,如下所示:

{
    "key1":"value1",
    "key2":"value2",
    "key3":"value3"
}

[编辑]

这是一个已知问题:http://jira.codehaus.org/browse/JACKSON-711(尚未修复)

答案

是的,您希望使用“委托”创建者(单个参数,首先绑定JSON输入) - 不同于“基于属性”的创建者,其中传递了一组命名参数 - 以及可注入值(s)。这应该是理想的工作,但我认为它目前可能不起作用。我认为有一个Jira为此输入,所以你可以检查它(http://jira.codehaus.org/browse/JACKSON)。

只是为了确保:你使用的是1.9.2版吗?自1.9.0以来,已有一些修复;至少会给出更好的错误信息。

以上是关于在顶级地图上使用@JacksonInject和@JsonCreator的主要内容,如果未能解决你的问题,请参考以下文章

无法使用前导 .. 在顶级目录上退出

地图构建两篇顶级论文解析

地图构建两篇顶级论文解析

我的世界开发者发布地图的时候提醒压缩文件中,需要有一个顶级目录和server.properties文件是啥意思?

已经在 J​​ava 类中管理 ID 为 0 的 GoogleApiClient

2020 HDU校赛 Problem J