ObjectMapper必须使用JSON文件未提供的参数调用构造函数

时间:2019-06-17 23:04:05

标签: java jackson jackson-databind

我的目标是在我们的全局事件代理和Spring的ApplicationEvent系统之间建立某种桥梁。

消息代理以JSON格式提供消息。我的想法是要有一个

public class ExternalApplicationEvent extends ApplicationEvent {
   ...
   // e.g @JsonPropert private String name;
}

然后调用类似

objectMapper.readValue(brokerMessage, ExternalApplicationEvent.class);

问题在于,ApplicationEvent要求在构造时间上设置一个源 ,该源应该是ExternalEventBridge的实例,出于明显的原因,它不是其中的一部分JSON文档。

我发现了如何向JSON添加属性,这些属性不是使用@JsonAppend进行序列化的对象的一部分,但是我没有找到解决方法,无法将参数传递给类的构造函数

我最后的想法是使用

objectMapper.readerForUpdating(new ExternalApplicationEvent(theSource)).readValue(message)

但是以某种方式不能填写我的活动。

如果我添加构造函数

public ExternalApplicationEvent() {
  super(new Object());
}

并使用objectMapper.readValue(message, ExternalApplicationEvent.class),可以通过场注入正确地填充对象。另外添加Setters将无济于事。

1 个答案:

答案 0 :(得分:0)

我现在通过像这样从ApplicationEvent中分离数据来解决了这个问题:

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE) // Don't detect `getSource` from ApplicationEvent
public class ExternalApplicationEvent extends ApplicationEvent {

    // I might use @JsonUnwrapped probably, but since I have to create setters
    // and getters anyway...
    private ExternalApplicationEventData p = new ExternalApplicationEventData();

    public ExternalApplicationEvent(Object source, ExternalApplicationEventData data) {
        super(source);
        p = data;
    }

    @JsonGetter("name")
    public String getName() { return p.name; }

    public void setName(String name) { p.name = name; }

    public static class ExternalApplicationEventData {

        @JsonCreator
        private ExternalApplicationEventData() {} // Make creation only possible by parsing or from the ExternalApplicationEvent class

        @JsonProperty
        private String name;

        ...
    }
}

然后创建事件

var data = objectMapper.readValue(message, ExternalApplicationEvent.ExternalApplicationEventData.class);
var event = new ExternalApplicationEvent(this, data);