Десериализация Джексона из String не удалась - PullRequest
0 голосов
/ 09 июля 2019

Наша система использует Джексон (Java 11) для десериализации объектов из внешних источников.Когда мы получаем полезную нагрузку, она имеет формат String (UTF-8).Не удается десериализовать с исключением (MismatchedInputException)

Невозможно создать экземпляр объекта (хотя существует хотя бы один создатель): нет конструктора аргумента String / метода фабрики для десериализации из значения String ('{

Технология стека:

  • Java 11
  • Джексон 2.9.8
  • Google Cloud (платформа)

Мы закончилииспользование нескольких операторов replaceAll только для того, чтобы получить полезную нагрузку в состоянии, которое позволило бы преобразовать строку в объект в Джексоне. Код действительно пахнет ...

Я не уверен, что этопомогает, но полезная нагрузка извлекается из подписки Google PubSub. Итак, у меня получатель сообщений прослушивает подписку. Первоначально я использовал Springs JacksonPubSubMessageConverter , но выбрасывал исключение выше. Я развернул свое собственное, добавив replaceAll (..) ниже и теперь, кажется, это решило проблему.

public class ABCMessageReceiver implements MessageReceiver {
  private PubsubMessageConverter converter;
  public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
    Person person = converter.fromPubSubMessage(message, Person.class);
    ...
  }
}
payload = "{\n  \"general\": {\n    \"aggregatorId\": \"111111111111\",\n    \"communityId\": \"30303030\",\n    \"dateStamp\": \"2019-07-09\",\n    \"comments\": \"Testing E2E1\"\n  },\n  \"prospect\": {\n    \"firstName\": \"Joe\",\n    \"lastName\": \"Smith\",\n    \"nickName\": \"\",\n    \"email\": \"joe.smith@sample.com\",\n    \"gender\": \"MALE\",\n    \"maritalStatus\": \"SINGLE\",\n    \"dateOfBirth\": \"1956-06-15\",\n    \"veteranStatus\": \"NOTAVETERAN\",\n    \"address\": {\n      \"address1\": \"100 Acme Street \",\n      \"address2\": \"Suite 2300\",\n      \"city\": \"Acme City\",\n      \"state\": \"WI\",\n      \"zip\": \"53214\"\n    },\n    \"phones\": [\n      {\n        \"number\": \"4145551212\",\n        \"type\": \"WORK\"\n      }\n    ],\n    \"financial\": {\n      \"budgetAmount\": 2639,\n      \"budgetFrequency\": \"MONTHLY\",\n      \"medicaid\": true,\n      \"medicare\": true,\n      \"ltcPolicy\": false,\n      \"homeowner\": true,\n      \"vaAid\": false\n    },\n    \"prospectNeeds\": {\n      \"desiredCareLevel\": \"AL\"\n    }\n  },\n  \"tour\": {\n    \"date\": \"2019-07-14T17:00:00.000Z\",\n    \"notes\": \"Testing tour notes 1\"\n  }\n}"
payload = payload.replaceAll("\\\\\"", "\"");
payload = payload.replaceAll("\\\\n", "");
payload = payload.substring(1);
payload = payload.substring(0, payload.length()-1);

Мне не нравятся служебные строкизамены, но пока что это работает, пока я не получу другую перестановку строк, которую мне нужно поддерживать.

1 Ответ

0 голосов
/ 12 июля 2019

Я хотел бы поблагодарить @Andreas и других, которые предоставили комментарии.Сначала это не было связано с кодированием, я должен был вернуться к нему на следующий день.Да, я был бы рад, если бы продюсер представил правильно отформатированный JSON.Вот что я сделал, чтобы заставить это работать, не лучшее решение, но это работает.Я расширил JacksonPubSubMessageConverter.java и создал новую некодированную версию.

UnencodedJacksonPubSubMessageConverter.java

...
public <T> T fromPubSubMessage(PubsubMessage message, Class<T> payloadType) {
    try {
        String payload = message.getData().toStringUtf8();
        payload = removeQuotesIfNecessary(unescapePayload(payload));
        return (T) this.objectMapper.readerFor(payloadType).readValue(payload);
    }
    catch (IOException ex) {
        throw new PubSubMessageConversionException("JSON deserialization of an object of type " + payloadType.getName() + " failed.", ex);
    }
}

private String removeQuotesIfNecessary(String payload) {
    if (payload != null && payload.startsWith("\"") && payload.endsWith("\"")) {
        return payload.substring(1).substring(0, payload.length()-2);
    }
    return payload;
}

private String unescapePayload(String payload) {
    if (payload != null)
        return StringEscapeUtils.unescapeJson(payload);
    return payload;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...