Исключение при синтаксическом анализе Джексона - (хотя существует по крайней мере один создатель): нет конструктора аргумента String / фабричного метода для десериализации из значения String - PullRequest
0 голосов
/ 13 июня 2018
  • Версия Spring Boot: 1.5.10
  • Версия Jackson: 2.9.5
  • Версия Lombok: 1.18.0

У меня есть сценарийкуда я отправляю полезную нагрузку с помощью кафки.Получив эту полезную нагрузку, я пытаюсь установить, одинаковы ли полезная нагрузка на стороне получателя и отправителя.

Сначала я создал класс, который будет передан в качестве полезной нагрузки.Структура класса приведена ниже.Используемая версия плагина lombok - 1.18.0.

@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDummyClass implements Serializable{

    private static final long serialVersionUID = -4181985100899233094L;
    private String data;
    private String id;
}

Для вышеупомянутого pojo я создал модульный тест, в котором я передаю строку и пытаюсь преобразовать ее из String в объект, который работает безлюбая проблема .

@Test
public void shouldBeAbleToConvertStringToDesiredObjectType() throws IOException {
    String s = "{\r\n  \"data\" : \"foo\",\r\n  \"id\" : \"xyz\"\r\n}";
    MyDummyClass myDummyClass = convertValue(s, MyDummyClass.class);
    assertThat(myDummyClass.getData(), is("foo"));
}

Кроме того, ниже приведена конфигурация картографа Джексона.

private static final ObjectMapper mapper = new ObjectMapper();

static {
    mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
    mapper.disable(FAIL_ON_UNKNOWN_PROPERTIES);
    mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
    mapper.enable(ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
    mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
    // Skip the Null Values
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    mapper.disableDefaultTyping();

    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); //YYYY-MM-DDThh:mm:ss.sTZD (e.g. 1997-07-16T19:20:30.45.003+01:00)
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    mapper.setDateFormat(dateFormat);
}

Теперь перейдем к основной формулировке проблемы.Таким образом, в моем другом тестовом случае, когда я отправляю полезную нагрузку через kafka и после получения ответа от темы kafka, я пытаюсь преобразовать входящие данные String в нужный тип класса MyDummyClass .В моем тестовом примере я поместил оператор logger, чтобы увидеть, какое значение я получаю.Я вижу, что получаю точно такое же строковое значение, которое указано в приведенном выше тесте.Но во время синтаксического анализа этого текста к желаемому типу MyDummyClass я получаю ошибку (хотя существует хотя бы один создатель): отсутствует конструктор аргумента строки / фабричный метод для десериализации из значения String.

@Test
public void messageWithAnyContractObjectCanBeConvertedToSameObjectAtTheListenerEnd() throws InterruptedException, IOException, JSONException {
    String correlationID = UUID.randomUUID().toString();
    String id = UUID.randomUUID().toString();
    MyDummyClass actualPayload = MyDummyClass.builder().data("foo").id("xyz").build();
    Message message = MessageBuilder.withAnyMessage()
            .withNoHeader(BaseHeader.builder().ID(id).correlationID(correlationID).sendToDestination("my-topic").build())
            .payload(actualPayload)
            .build();
    messagePublisher.publishMessage(message, DEFAULT_PUBLISHER_OPTIONS);

    String recordedString = records.poll(10, TimeUnit.SECONDS).value();
    LOGGER.info("Receiving Response {}", recordedString);
    MyDummyClass recordedValue = convertValue(recordedString, MyDummyClass.class);

    assertThat(recordedValue.getData(), is(actualPayload.getData()));
}

Подробный журнал ошибок: enter image description here

1 Ответ

0 голосов
/ 21 июня 2018

Наконец-то я смог решить эту проблему.Эта проблема возникла из-за неправильного кода, написанного на стороне моего кода издателя, где сначала я шифровал свою полезную нагрузку, конвертируя введенную полезную нагрузку как объект json (используя Джексона), позже я снова сохранял эту полезную нагрузку json внутри объекта с заголовком и пыталсяпреобразовать этот объект в строку (снова используя конвертер Джексона).В этом процессе я дважды преобразовывал всю полезную нагрузку в строку, в результате чего я вносил дополнительные \r\n в свою полезную нагрузку, которую я отправлял через kafka.При преобразовании обратно в объект из json в объект этот дополнительный \r\n вызывал проблему, которую я вставил ранее.

В качестве решения я сохранил уже преобразованный объект json в другой объект с аннотацией Джексона @ JsonRawData .Это предотвращает добавление дополнительных \r\n.

...