java - 在顶级 map 上使用@JacksonInject 和@JsonCreator

标签 java json map deserialization jackson

使用 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。获得访问我称之为“顶级 map ”的权限让事情变得简单。

我想以这种方式反序列化我的对象,因为它还允许创建不可变对象(immutable对象),而不是使用 @JsonAnySetter这不允许这样做,并且@JsonProperty正如我之前提到的,我无法使用它,因为我事先不知道属性名称。

然后更进一步,我想在我的工厂方法中注入(inject)一些配置,Jackson 通过使用 @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);
    }
}

不幸的是,Jackson 会抛出以下类型的异常:

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

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

有谁知道我该如何解决这个问题?

总结需求,我需要:

  • 获取顶层 map (事先不知道json属性名)
  • 创建一个不可变对象(immutable对象)(所以不能使用 @JsonAnySetter )
  • @JsonCreator 注入(inject)一些配置文件修饰的构造函数或工厂方法

我无法更改 json 输入格式,它看起来像这样:

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

[编辑]

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

最佳答案

是的,您希望同时使用“委托(delegate)”创建者(单个参数,首先将 JSON 输入绑定(bind)到其中)——不同于传递命名参数集的“基于属性”的创建者——和可注入(inject)值(秒)。这在理想情况下应该可以工作,但我认为目前可能行不通。 我认为为此输入了一个 Jira,因此您可以查看它 ( http://jira.codehaus.org/browse/JACKSON )。

只是为了确定:您使用的是 1.9.2 版吗?自 1.9.0 以来,已经对此进行了一些修复;这至少会给出更好的错误信息。

关于java - 在顶级 map 上使用@JacksonInject 和@JsonCreator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8339282/

相关文章:

c# - Razor @Json.Serialize 对各个属性的处理在 ASP.NET Core 中不一致

c++ - 为什么需要配对才能插入 map ?

scala - 如何获取 map 的子集?

map - 如何使用 ffmpeg 同时编码具有不同选项的多音频流

java - 不能使用方法?

java - Apache httpclient 从本地文件系统获取文件?

javascript - 使用 Jquery 搜索 JSON

json - 在golang中动态创建嵌套 map

java - SWt : what is the color of a Control's border?

Java nashorn 比较一个 java 对象是否属于某种 java 类型