ObjectMapper должен вызывать конструктор с аргументами, не предоставленными в файле JSON - PullRequest
2 голосов
/ 18 июня 2019

Моя цель - создать какой-то мост между нашим глобальным посредником событий и системой SpringE 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), объект будет правильно заполнен путем внедрения поля.Также добавление сеттеров не поможет.

1 Ответ

0 голосов
/ 18 июня 2019

Я решил это сейчас, отделив Данные от 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);
...