2016-02-29 3 views
4

Я использую Jackson для десериализации JSON из API ReST API на Java с использованием Jackson.Deserialize JSON, обернутый в объект с неизвестным именем свойства, используя Jackson

Проблемы я столкнулся в том, что один конкретный ответ ReST возвращается, завернутый в объекте, на который ссылается числовым идентификатором, например:

{ 
    "1443": [ 
    /* these are the objects I actually care about */ 
    { 
     "name": "V1", 
     "count": 1999, 
     "distinctCount": 1999 
     /* other properties */ 
    }, 
    { 
     "name": "V2", 
     "count": 1999, 
     "distinctCount": 42 
     /* other properties */ 
    }, 
    ... 
    ] 
} 

Мой (возможно, наивный) подход к десериализации JSON вплоть до этот момент состоял в том, чтобы создать POJO зеркального изображения и позволить Джексону отображать все поля просто и автоматически, что хорошо.

Проблема в том, что ответ ReST JSON имеет динамическую, числовую ссылку на массив POJO, который мне действительно нужен. Я не могу создать зеркальную оболочку POJO, потому что само имя свойства является как динамическим, так и незаконным именем свойства Java.

Буду признателен за любые предложения по маршрутам, которые я могу исследовать.

+0

A) Ваш JSON недействителен: отсутствует символ ']'. B) Используйте массив объектов, чтобы предотвратить проблему (если я достаточно понимаю ваш образец, так как он немного ограничен) –

+0

A) Спасибо; Я обновил образец JSON B) Конечно, массив объектов - это точно моя цель, но я не могу на самом деле добраться до массива вообще, поскольку на него ссылается имя свойства, которое является динамическим и незаконным в Java –

ответ

3

Самое простое решение без пользовательских deserializers является использование @JsonAnySetter. Джексон будет вызывать метод с помощью этой аннотации для каждого неотображенного свойства.

Например:

public class Wrapper { 
    public List<Stuff> stuff; 

    // this will get called for every key in the root object 
    @JsonAnySetter 
    public void set(String code, List<Stuff> stuff) { 
    // code is "1443", stuff is the list with stuff 
    this.stuff = stuff; 
    } 
} 

// simple stuff class with everything public for demonstration only 
public class Stuff { 
    public String name; 
    public int count; 
    public int distinctCount; 
} 

Чтобы использовать его, вы можете просто сделать:

new ObjectMapper().readValue(myJson, Wrapper.class); 

другой путь вокруг вы можете использовать @JsonAnyGetter, который должен возвращать Map<String, List<Stuff>) в этом случае.

1

Я думаю, что самым простым решением является использование пользовательского JsonDeserializer. Это позволяет вам поочередно анализировать входные данные и извлекать только те сведения, которые вам нужны для создания вашего объекта.

Вот простой пример того, как реализовать пользовательский десериализатор: custom jackson deserializer

+0

Я боялся, что это может стать уродливым. Я займусь этим. –

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