Ниже вы можете увидеть мой десериализатор «Список».

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

public static class Pojo {
    public String foo;

    @JsonRawValue
    public String bar;
}

@Test
public void test() throws JsonGenerationException, JsonMappingException, IOException {

    String foo = "one";
    String bar = "{\"A\":false}";

    Pojo pojo = new Pojo();
    pojo.foo = foo;
    pojo.bar = bar;

    String json = "{\"foo\":\"" + foo + "\",\"bar\":" + bar + "}";

    ObjectMapper objectMapper = new ObjectMapper();
    String output = objectMapper.writeValueAsString(pojo);
    System.out.println(output);
    assertEquals(json, output);

    Pojo deserialized = objectMapper.readValue(output, Pojo.class);
    assertEquals(foo, deserialized.foo);
    assertEquals(bar, deserialized.bar);
}

Код выводит следующую строку:

{"foo":"one","bar":{"A":false}}

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

org.codehaus.jackson.map.JsonMappingException: Невозможно десериализовать экземпляр java.lang.String из токена START_OBJECT в [Source: [email protected]; строка: 1, столбец: 13] (через цепочку ссылок: com.tnal.prism.cobalt.gather.testing.Pojo ["bar"])

Почему Джексон прекрасно работает в одном направлении, но не работает при движении в другом направлении? Похоже, что он должен быть в состоянии взять свой собственный вывод в качестве ввода снова. Я знаю, что я пытаюсь сделать, это неортодоксально (общий совет - создать внутренний объект дляbar который имеет свойство с именемA), но я не хочу взаимодействовать с этим JSON вообще. Мой код действует как проход для этого кода - я хочу взять этот JSON и снова отправить его обратно, не затрагивая ничего, потому что, когда JSON изменяется, я не хочу, чтобы мой код нуждался в изменениях.

Спасибо за совет.

РЕДАКТИРОВАТЬ: сделал Pojo статическим классом, который вызывал другую ошибку.

Ответы на вопрос(1)

Решение Вопроса

@JsonRawValue предназначен только для стороны сериализации, поскольку обратное направление немного сложнее обрабатывать. он был добавлен, чтобы позволить вводить предварительно закодированный контент.

Я предполагаю, что можно было бы добавить поддержку реверса, хотя это было бы довольно неловко: контент нужно будет проанализировать, а затем переписать обратно в «сырую» форму, которая может совпадать или не совпадать (так как цитирование символов может отличаться). Это для общего случая. Но, возможно, это имело бы смысл для некоторой подгруппы проблем.

Но я думаю, что обходным решением для вашего конкретного случая было бы указать тип как 'java.lang.Object', поскольку это должно работать нормально: для сериализации String будет выводиться как есть, а для десериализации она будет десериализована как карта. На самом деле вы можете захотеть иметь отдельный геттер / сеттер, если так; getter возвращает String для сериализации (и нуждается в @JsonRawValue); и установщик будет принимать либо карту, либо объект. Вы можете перекодировать его в строку, если это имеет смысл.

 yves amsellem12 июл. 2012 г., 14:55
Этот ж, как шарм; смотри мой ответ по коду (форматирование в комментариях).
 Sid10 февр. 2016 г., 16:09
У меня был другой вариант использования для этого. Похоже, что если мы не хотим генерировать много строкового мусора в deser / ser, мы должны просто пропустить строку как таковую. Я видел поток, который отслеживал это, но, кажется, нет никакой встроенной поддержки. Посмотри наmarkmail.org/message/...
 StaxMan12 февр. 2016 г., 22:43
@ Сид нет способа сделать это и токенизацию эффективно. Для поддержки сквозного прохождения необработанных токенов потребуется дополнительное сохранение состояния, что делает «регулярный» анализ несколько менее эффективным. Это своего рода оптимизация между обычным кодом и выдачей исключений: поддержка последнего добавляет издержки для первого. Джексон не был разработан, чтобы пытаться поддерживать доступ необработанного ввода; было бы неплохо иметь его (и для сообщений об ошибках), но потребовал бы другого подхода.

Ваш ответ на вопрос