Лучший способ декодировать строку JSON в объект Java?

У меня есть ServerEndpoint, который будет получать разные форматы JSON. Поскольку нам разрешен только один обработчик сообщений для каждого типа сообщения, мой единственный декодер должен будет преобразовать сообщение в соответствующие объекты Java.

В моем декодере я пытаюсь преобразовать полученное сообщение либо в SubClassA, либо в SubClassB (который реализует тот же интерфейс), используя класс ObjectMapper. Класс ObjectMapper имеет метод readValue, для которого требуется тип, с которым я пытаюсь сопоставить json, и выдает исключение, когда он не может преобразовать в указанный тип.

В настоящее время я расшифровываю его следующим образом, но это не очень элегантно.

@Override
public Message decode(String message) throws DecodeException {
    ObjectMapper mapper = new ObjectMapper();

    try {
        SubclassA obj = mapper.readValue(message, SubclassA .class);
        return obj;
    } catch (IOException e) {
    }

    try {
        SubclassB obj = mapper.readValue(message, SubclassB .class);
        return obj;
    } catch (IOException e) {
    }

    throw new DecodeException(message, "Failed to decode message.");
}

Как лучше всего декодировать строку JSON в соответствующий объект Java с помощью ObjectMapper?


person dalawh    schedule 31.08.2016    source источник


Ответы (2)


Используйте Джексона, вы можете объявлять подтипы для родительского объекта. Ваш Json будет содержать @type с именем подтипа, посмотрите этот пост Десериализовать JSON с Джексоном в полиморфные типы — полный пример дает мне ошибку компиляции

person Vitalii Kravchenko    schedule 31.08.2016
comment
Можно ли не включать тип в JSON и при этом работать? - person dalawh; 31.08.2016
comment
это невозможно, вы также можете взломать, реализовав стратегию повторных попыток для десериализации объекта с разными классами. Второй вариант - добавить поле с именем класса и во время десериализации получить имя класса и прочитать Json - person Vitalii Kravchenko; 31.08.2016
comment
Хак - это то, чем я сейчас пользуюсь, что мне совсем не нравится. - person dalawh; 31.08.2016
comment
Тогда используйте подход Джексона - person Vitalii Kravchenko; 31.08.2016
comment
Я не могу изменить JSON, так как в некоторой степени не контролирую входящие сообщения. - person dalawh; 31.08.2016
comment
Давайте продолжим обсуждение в чате. - person Vitalii Kravchenko; 31.08.2016

Jackson — один из лучших вариантов для работы с JSON в Java.

Для полиморфной десериализации рассмотрите следующее:

  • Использование аннотации @JsonTypeInfo .
  • Для ситуаций, когда @JsonTypeInfo аннотация не подходит, рассмотрите возможность использования StdDeserializer. Этот ответ поможет вам.
person cassiomolin    schedule 31.08.2016
comment
StdDeserializer выглядит довольно интересно и выглядит так, как будто бы он работал. К сожалению, SubclassA не имеет уникального поля. - person dalawh; 31.08.2016
comment
@dalawh Как выглядят SubclassA и SubclassB? - person cassiomolin; 01.09.2016
comment
SubClassA и SubClass B расширяют разные классы, но реализуют один и тот же интерфейс. - person dalawh; 06.09.2016