2016-12-22 5 views
2

Я использую Весна/Spring загрузки и Spring MVC с @RestControllerSpring REST JSON сериализации/десериализации композитных полиморфных типов

У меня есть составные объекты модели:

public abstract class BaseQuery { 

    private final Long characteristicId; 

... 

} 

public abstract class ComparableQuery extends BaseQuery { 

    private final Object value; 

    private final String comparisonOperator; 

... 

} 

public class GreaterOrEqualQuery extends ComparableQuery { 

    public GreaterOrEqualQuery(Long characteristicId, Object value) { 
     super(characteristicId, value, ">="); 
    } 

} 

public class EqualQuery extends ComparableQuery { 

    public EqualQuery(Long characteristicId, Object value) { 
     super(characteristicId, value, "="); 
    } 

} 

public class GreaterQuery extends ComparableQuery { 

    public GreaterQuery(Long characteristicId, Object value) { 
     super(characteristicId, value, ">"); 
    } 

} 

public class CompositQuery extends BaseQuery { 

    private final String operator; 
    private final BaseQuery[] queries; 

    public CompositQuery(Long characteristicId, Operator operator, BaseQuery... queries) { 
     super(characteristicId); 
     this.operator = operator.value; 
     this.queries = queries; 
    } 

... 

} 

т.д.

пример использования этой модели выглядит, например, как:

Set<BaseQuery> queries = new HashSet<>(); 

BaseQuery megapixelCharacteristicQuery = new CompositQuery(megapixelCharacteristic.getCharacteristicId(), CompositQuery.Operator.AND, new GreaterOrEqualQuery(megapixelCharacteristic.getCharacteristicId(), 10), new LessOrEqualQuery(megapixelCharacteristic.getCharacteristicId(), 50)); 
queries.add(megapixelCharacteristicQuery); 
queries.add(new EqualQuery(androidCharacteristic.getCharacteristicId(), true)); 

Серийный номер JSON объект для Set<BaseQuery> queries выглядит следующим образом:

[ 
    { 
     "operator":"AND", 
     "queries":[ 
     { 
      "value":10, 
      "comparisonOperator":"\u003e\u003d", 
      "characteristicId":391 
     }, 
     { 
      "value":50, 
      "comparisonOperator":"\u003c\u003d", 
      "characteristicId":391 
     } 
     ], 
     "characteristicId":391 
    }, 
    { 
     "value":true, 
     "comparisonOperator":"\u003d", 
     "characteristicId":383 
    } 
] 

Я должен передать это или подобное JSON из клиентского приложения (AngularJS) на мой задний конец REST API конечной точки, чтобы получить правильно десериализованное модель, как описано выше (Установить с соответствующими записями например CompositQuery или EqualQuery).

Прямо сейчас моя логика конца приложения Spring на моем контроллере останова неспособна правильно десериализовать этот JSON с соответствующими классами.

Возможно ли каким-либо образом весной предоставить некоторую метаинформацию (или что-то еще) для этого JSON, чтобы помочь Spring правильно десериализовать эту структуру?

ответ

2

Вы можете достичь этого, используя Джексон аннотации на суперклассе, как следующее:

import com.fasterxml.jackson.annotation.JsonIgnore; 
import com.fasterxml.jackson.annotation.JsonSubTypes; 
import com.fasterxml.jackson.annotation.JsonSubTypes.Type; 
import com.fasterxml.jackson.annotation.JsonTypeInfo; 

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "javaclass") 
@JsonSubTypes({ 
    @Type(value = GreaterOrEqualQuery.class), 
    @Type(value = EqualQuery.class) 
    //and so on... 
}) 
public abstract class BaseQuery { 
    ... 
} 

Это добавит javaclass свойства в представление JSON, который является полностью квалифицированным именем в случае use = JsonTypeInfo.Id.CLASS. Чтобы упростить значение этого свойства, рассмотрите различные параметры для параметра use@JsonTypeInfo (например, JsonTypeInfo.Id.NAME).