JSON to Java Objects, лучшая практика для моделирования потока json - PullRequest
3 голосов
/ 23 марта 2012

У меня есть поток JSON, генерируемый серверной программой C ++, которая в данный момент находится в разработке.Мне дали образец полученного JSON, и я обеспокоен тем, что мне придется анализировать json вручную, что я не смогу использовать нормальное отображение классов, предоставляемое такими инструментами, как GSON или Jackson.

Пожалуйста, посмотрите на следующий (несколько) надуманный пример, который они предоставили.Разделы, которые меня интересуют, - это массив метаданных "serie", имеющий разные параметры.Ключ - «ключ», например, присутствует только в одном из элементов массива.Не вызовет ли это проблем при попытке сопоставить этот массив с коллекцией определенного класса?

Наконец, я обеспокоен тем, что объект "point" не похож.У меня очень ограниченное понимание JSON (будучи старомодным Java-разработчиком Swing), но тот факт, что пары «точечные» значения ключа могут быть разными - это проблема.описать таблицу со способами отображения прогресса и предоставить механизм для запроса «большего» от базового оборудования.Также, если вам интересно, почему, я делюсь этим потоком данных с тонким клиентом (html-браузер).

Итак, я прав, что это не будет легко конвертировать в объекты Java?Спасибо за любой совет, который вы можете дать.

-D Klotz

Ответы [ 3 ]

4 голосов
/ 23 марта 2012

В GSON, при условии, что класс, в который вы десериализуете, имеет поля для всех имен, которые появляются в JSON, поля, не найденные в JSON, просто останутся пустыми:

https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects

"При десериализации пропущенная запись в JSON приводит к тому, что соответствующему полю в объекте присваивается значение null"

Все становится немного сложнее, если в JSON допускаются произвольные имена полей - например,если точка позволяет c1, c2, ... cn.Но вы можете справиться с этим с помощью специального десериализатора.

https://sites.google.com/site/gson/gson-user-guide#TOC-Writing-a-Deserializer

Редактировать:

Вот как вы можете написать собственный десериализатор для Point:

private class DateTimeDeserializer implements JsonDeserializer<Point> {
    public Point deserialize(JsonElement json, Type typeOfT, 
            JsonDeserializationContext context) throws JsonParseException {
        List<PointPart> parts = Lists.newArrayList();

        for(Map.Entry<String,JsonElement> entry : 
                json.getAsJsonObject().entrySet()) {
            char type = ;
            int index = Integer.parseInt(entry.getKey().substring(1)) - 1;

            while(parts.size() <= index) {
                parts.add(new PointPart());
            }

            PointPart part = parts.get(index);
            switch(entry.getKey().charAt(0)) {
            case 'c':
                part.c = entry.getValue().getAsBoolean();
                break;
            case 'k':
                part.k = entry.getValue().getAsInt();
                break;
            }
        }

        return new Point(parts);
    }
}

class Point {
    List<PointPart> parts;

    Point(List<PointPart> parts) {
        this.parts = parts;
    }
}

class PointPart {
    boolean c;
    int k;
}
2 голосов
/ 23 марта 2012

Я бы больше интересовался тем, что выглядит как поля метаданных в потоке данных. Атрибуты верхнего уровня 'abort' и 'more' выглядят как некая структурированная строка, которую вам, возможно, придется проанализировать? Кроме того, вам просто нужно смоделировать каждый объект Java с максимально широким набором полей, которые будут отправлены из вашей внешней программы. Вам не нужно беспокоиться, если в передаваемых данных пропущено одно или несколько полей, в этом случае большинство библиотек JSON просто десериализуют нуль. Кроме того, большинство библиотек JSON также позволяют указать, что вы хотите игнорировать неизвестные входящие поля.

Таким образом, между десериализацией null для пропущенных полей и игнорированием дополнительных полей вы должны хорошо разобраться.

1 голос
/ 23 марта 2012

Нет, это не особенно сложно для десериализации в объекты Java.JSON не имеет много подсказок о вводе информации, кроме их примитивов.Большая часть беспокойства о потере информации о типах может быть восстановлена ​​либо просмотром объекта, в который вы хотите десериализоваться, либо предоставлением пользователю объекта, в который он хочет десериализоваться.Именно так работает flexjson, и у вас есть большая гибкость, чтобы определить в каждой точке, как его десериализовать.Он поставляется с разумными значениями по умолчанию для большинства проблем, но вы всегда можете присоединить ObjectFactory к определенному классу или пути в потоке JSON.

http://flexjson.sourceforge.net

...