как быть с интерфейсами у jackson?

Я занимаюсь этой проблемой. У меня есть этот класс:

public class SemaphoreResponse {
    ISemaphore semaphore;
    StatusHolder statusHolder;

    public SemaphoreResponse() {
        super();
    }

    // Getters and setters
}

Я хочу преобразовать свою строку json в этот класс, и он выдает мне это исключение

org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.despegar.henry.automation.services.semaphoreservice.response.ISemaphore, problem: abstract types can only be instantiated with additional type information
at [Source: java.io.StringReader@17a5f5a5; line: 1, column: 2] (through reference chain: com.despegar.henry.automation.services.semaphoreservice.response.SemaphoreResponse["semaphore"])
at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
at org.codehaus.jackson.map.deser.StdDeserializationContext.instantiationException(StdDeserializationContext.java:233)
at org.codehaus.jackson.map.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:60)
at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)

Итак, я понимаю, что это происходит из-за атрибута «семафор», который является интерфейсом, поэтому я знаю, что в этот интерфейс я должен добавить @JsonDeseralize вот так

@JsonDeserialize(as = [class-name].class)
public interface ISemaphore {
    public abstract String getId();

    public abstract void setId(String id);

    public abstract String getOwnerUserId();

}

Но это моя проблема. Семафор атрибута из SemaphoreResponse не всегда использует один и тот же класс. следовательно, у меня есть два разных класса, называемых «MainSemaphore» и «ExecutionSemaphore», оба из которых реализуют интерфейс ISemaphore. Итак, во время десериализации я хочу передать класс, для которого я хочу, чтобы интерфейс адаптировался в качестве параметра.

Это было бы что-то вроде

@JsonDeserialize(as = MainSemaphore.class) or @JsonDeserialize(as = ExecutionSemaphore.class) depending the case

Как я мог это сделать? буду признателен за вашу помощь


person jscherman    schedule 29.07.2014    source источник
comment
Есть несколько способов сделать это. См. эту статью со ссылкой на этот вопрос   -  person Jeff    schedule 29.07.2014
comment
@llawj ссылается на правильный способ обработки полиморфизма, но я подозреваю, что вы не получите ожидаемых результатов сериализации семафора...   -  person Baldy    schedule 30.07.2014
comment
Спасибо! мне помогло! С уважением   -  person jscherman    schedule 30.07.2014
comment
Вы знаете, как установить путь к свойству? Я не могу найти это нигде. Потому что я сопоставляю свойство StatusHolder (которое сейчас является абстрактным классом) и для создания полиморфизма оно зависит от атрибута типа, расположенного в семафоре. Вы знаете, как это сделать? Я не знаю, ясно ли я, иначе дайте мне знать. С уважением   -  person jscherman    schedule 01.08.2014
comment
При наличии нескольких реализаций вам необходимо использовать аннотацию @JsonTypeInfo в интерфейсе; и JSON должен каким-либо образом включать идентификатор типа (либо в качестве дополнительного свойства, либо с использованием объекта-оболочки или массива, где идентификатор типа является либо ключом (для объекта), либо первым элементом (для массива). Таким образом, статья ProgrammerBruce помогает здесь.   -  person StaxMan    schedule 08.08.2014


Ответы (1)


Помимо полной полиморфной обработки, описанной в отличной статье ProgrammerBruce, есть также более простой способ просто поддерживать простой интерфейс/импл, один к одному, case: отображение регистров через модуль:

SimpleModule m = new SimpleModule(...); m.addAbstractTypeMapping(ISemaphore.class, SemaphoreImpl.class); mapper.registerModule(m);

и это будет указывать Джексону всегда десериализовать вещи, объявленные как ISemaphore, используя конкретный класс SemaphoreImpl.

person StaxMan    schedule 30.07.2014
comment
Спасибо! я уже решил! но у меня теперь есть еще одна проблема. Я описал это нам комментарий вверх. С уважением - person jscherman; 01.08.2014