2013-11-27 5 views
2

Допустим, у меня есть иерархия объектов JSON вроде следующего:денормализации вложенными JSON объект иерархий в Джексон

{ 
    "name": "Mosquito Laser", 

    "configurations": [{ 
     "currency": "USD", 
     "price": "10.00" /* the Basic option */ 
    }, { 
     "currency": "USD", 
     "price": "50.00" /* the Pro option */ 
    }, ] 

} 

Я хотел бы десериализации этот JSON в объект Java, и придавить его в один уровень. Так, например, я хотел бы, чтобы отобразить выше JSON в следующий класс Java:

@JsonIgnoreProperties(ignoreUnknown = true) 
public class Product { 

    @JsonProperty 
    protected String name; 

    protected String lowestPrice; 
    protected String highestPrice; 

} 

Я хотел бы использовать специальный метод для вычисления lowestPrice и highestPrice полей из списка конфигураций в формате JSON. Предположим ради аргумента, что json-иерархия и объект java были упрощены здесь для ясности, и что на самом деле они на самом деле намного сложнее, поэтому я не хочу реализовывать полностью настраиваемый десериализатор. Я хочу, чтобы большая часть полей была автоматически десериализована с использованием настроек привязки по умолчанию для Jackson, но я хочу указать настраиваемые операции для определенных полей.

Есть ли простой способ рассказать Джексону использовать специальный метод для автоматического вычисления значений полейи highestPrice?

ответ

2

Использование:

@JsonProperty("configuration") 
@JsonDeserialize(using = ConfigurationDeserializer.class) 
protected String cheapestPrice; 

И десериализатор выглядит следующим образом:

public class ConfigurationDeserializer extends JsonDeserializer<String> { 

    @Override 
    public String deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException { 
     (your logic to go from the configuration JSON to cheapestPrice goes here) 
    } 
} 
+0

Итак, это хорошее решение, однако я понял, что у меня есть дополнительное ограничение, которое я не понимал, было важно. Мне действительно нужно вычислить MULTIPLE вычисляемые поля, а не только один. Я не уверен, как это сделать с этим решением, поскольку вычисление первого поля проглотит токены в потоковом парсере. Я обновлю вопрос – emmby

+0

@emmby, я думаю, тогда единственным решением является наличие определенного класса для этих двух полей. Или используйте Desierializer в своем родительском классе. –

2

В ETL и SQL, это объединение. Несколько вопросов:

  • Вам нужны агрегированные значения?
  • Вам нужны другие значения от JSON более низкого уровня?
  • Является ли память проблемой?
  • Является ли ЦП проблемой?

Комментарии:

  • Aggregation требует сохранения состояния при разборе древовидных структур
  • быстрых потоковые парсеры не сохранить состояние
  • государство может либо передаваться в ребенок или может быть возвращено обратно от детей.
  • Джексон может быть медленным при анализе ненужных дочерних значений.
+0

Хотя этот ответ может дать некоторое представление о решении вопроса OP, рекомендуется включить некоторые примеры кода, демонстрирующие концепции, изложенные в ответе. – NaijaProgrammer

1

Если все, что вам нужно изменить значения только определить метод получения (ы):

public class Product { 
    public String name; 

    protected String lowestPrice; 
    protected String highestPrice; 

    public int getLowestPrices() { 
    return calculateLowest(lowestPrice); 
    } 
    // and similarly for highestPrice... 
} 

или, при чтении JSON в, определить соответствие сеттера. Методы имеют приоритет над полями.

Смежные вопросы