Джексон генерирует исключение JsonMappingException при десериализации;требует однострокового конструктора? - PullRequest
11 голосов
/ 03 декабря 2011

Еще один вопрос, но он относится к этому: Десериализация JSON с Джексоном - почему JsonMappingException «Нет подходящего конструктора»?

На этот раз я получаю другую ошибку, а именно то, что десериализатор Джексона жалуется, что у меня нет «конструктора / фабрики с одной строкой» в моем классе ProtocolContainer.

Однако, если я добавлю одностроковый конструктор, например:

public ProtocolContainer(String json) {}

исключение действительно исчезает, но ProtocolContainer, который я ожидал там, все "пусто", то есть все его свойства находятся в исходном состоянии и не заполняются в соответствии со строкой JSON.

Почему это?

Я почти уверен, что вам не нужен одностроковый конструктор, и если вы сделаете это, вам не нужно будет заполнять свойства в этом конструкторе, верно?

=)

Ответы [ 4 ]

19 голосов
/ 03 декабря 2011

О, так я еще раз узнал ответ ПОСЛЕ того, как я опубликовал этот вопрос (хотя я пытался много чего сделать перед публикацией).

Что я сделал, чтобы решить эту проблему, так это использовать @JsonCreatorаннотаций.Я просто аннотировал свой статический метод Create, например:

@JsonCreator
public static ProtocolContainer Create(String jsonString)
{

    ProtocolContainer pc = null;
    try {
        pc = mapper.readValue(jsonString, ProtocolContainer.class);
    } catch (JsonParseException|JsonMappingException|IOException e) {
        // handle
    }

    return pc;
}

И тогда проблема решена.

18 голосов
/ 04 декабря 2011

Исключение говорит о том, что значение JSON, которое у вас есть, является строкой, что-то вроде:

{ "protocol" : "http" }

или, возможно, "JSON в двойных кавычках":

"\"{\"property\":\"value\"}\"

при попытке связать как:

ProtocolContainer p = mapper.readValue(json, ProtocolContainer.class);

В этом случае у Джексона нет свойств для сопоставления, только строка. И в этом случае он действительно требует либо собственного десериализатора, либо метода создателя. Методы-создатели являются либо конструкторами с одностроковым аргументом, либо статическими методами с одностроковым аргументом: разница в том, что только конструкторы могут быть обнаружены автоматически (это просто практический ярлык, поскольку может быть только один такой конструктор, но несколько статические методы).

Ваше решение действительно работает, просто подумал, что я бы немного рассказал о том, что происходит.

Читая его во второй раз, кажется более вероятным, что у вас есть двойные кавычки (JSON в JSON): еще одна вещь, которую следует рассмотреть, - это получить простой JSON, если это возможно. Но, может быть, это трудно сделать.

1 голос
/ 29 июня 2017

У меня была такая же проблема.Для меня решение было переключиться с передачи String на convertValue метод, с InputStream на readValue метод:

// Instead of this:
String jsonString = "..."
ProtocolContainer pc = mapper.convertValue(jsonString, ProtocolContainer.class);

// ... do this:
String jsonString = "..."
InputStream is = new StringInputStream(jsonString);
ProtocolContainer pc = mapper.readValue(is, ProtocolContainer.class);
0 голосов
/ 27 мая 2015

Похоже, вы отправляете на сервер строку вместо объекта.

Вместо отправки строки для анализа на стороне сервера, вы можете сделать это проще, просто отправив JSON.parse(stringObject), и Джексон будет десериализовать ее как обычно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...