как да се справя с интерфейсите в 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)

И така, разбирам, че това се случва, защото атрибутът "semaphore", който е интерфейс, така че в този интерфейс знам, че трябва да добавя @JsonDeseralize по този начин

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

    public abstract void setId(String id);

    public abstract String getOwnerUserId();

}

Но това си е мой проблем. Атрибутът semaphore от 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 (което в момента е абстрактен клас) и за да направя полиморфизъм, зависи от атрибута тип, разположен в Semaphore. Знаете ли как да го направите? Не знам дали съм ясен, иначе ме уведомете. за разбирането   -  person jscherman    schedule 01.08.2014
comment
При повече от една реализация трябва да използвате @JsonTypeInfo анотация на интерфейса; и JSON трябва да има идентификатор на тип, включен по някакъв начин (или като допълнително свойство, или с помощта на обвивка на обект или масив, където идентификаторът на типа е или ключ (за обект), или първи елемент (за масив). Така че статията на ProgrammerBruce помага тук.   -  person StaxMan    schedule 08.08.2014


Отговори (1)


Освен пълната полиморфна обработка, описана в отлична статия от ProgrammerBruce, има и по-прост начин просто да поддържате прост интерфейс/impl, едно към едно, 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