Spring Integration 5.2.2.RELEASE - преобразование потока интеграции с @IntegrationConverter не работает с привязкой данных Джексона - PullRequest
1 голос
/ 06 января 2020

Я обновляю свою версию Spring Boot с 2.1.8.RELEASE до 2.2.2.RELEASE (то есть Spring Integration с 5.1 до 5.2.2.RELEASE), и автомат c cast с @IntegrationConverter, похоже, больше не работает, если мы есть конвертер Джексона внутри подходящих пружинных конвертеров.

Конвертер объявляется автоматически, так как у меня есть зависимость от jackson-databind, объявленная в моих зависимостях проекта. Мне нужен Джексон, потому что я должен преобразовать полезную нагрузку, полученную от HTTP-запроса, в java bean-компонент. Но поскольку этот преобразователь объявлен, он используется вместо интеграции Spring GenericMessageConverter и не удается преобразовать, поскольку сначала пытается вызвать toString() в компоненте, а затем преобразовать представление объекта toString().

У меня есть образец в host в github: https://github.com/Kruschenstein/spring-integration-playground. Это простой поток интеграции Spring, где мы запускаем сервер, который запрашивает HTTP API в зависимости от ввода пользователя. Типичное использование приложения: ввод telnet localhost 1234 ввода числа от 0 до 255, и факт о кошке будет показан в пользовательском терминале.

Это журнал ошибок, который я получаю при отправке запрос от клиента telnet:

org.springframework.integration.transformer.MessageTransformationException: Failed to transform Message in bean 'server.transformer#2' for component 'server.org.springframework.integration.config.ConsumerEndpointFactoryBean#5'; defined in: 'org.grorg.integration.IntegrationApplication'; from source: 'bean method server'; nested exception is org.springframework.messaging.converter.MessageConversionException: Could not read JSON: Unrecognized token 'org': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
 at [Source: (String)"org.grorg.integration.model.api.Fact@22fae1e0"; line: 1, column: 4]; nested exception is com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'org': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
 at [Source: (String)"org.grorg.integration.model.api.Fact@22fae1e0"; line: 1, column: 4], failedMessage=GenericMessage [payload=org.grorg.integration.model.api.Fact@22fae1e0, headers={errorChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@cdb23ed, Server=Cowboy, ip_tcp_remotePort=54966, NUM=1, Connection=keep-alive, ip_localInetAddress=/127.0.0.1, ip_address=127.0.0.1, http_statusCode=200 OK, Date=1578329608000, Via=1.1 vegur, replyChannel=org.springframework.messaging.core.GenericMessagingTemplate$TemporaryReplyChannel@cdb23ed, Etag=W/"10db9-+ezvkUu4LsJ+zW4+jWiIrVy9v5E", ip_connectionId=localhost:54966:1234:2a75cd25-8e85-4b49-a124-4db58aac3b84, Set-Cookie=connect.sid=s%3A8-aFqwlU8601G1vSPXCnc4Wskla8GzpS.JBIKqFX1%2Fw%2BU7py1QOKqI2G1%2FdJNeUPBxGdGtbXQGIw; Path=/; HttpOnly, id=83b6790f-27f0-6045-3e0e-8b852ca10b46, Content-Length=69049, contentType=application/json;charset=utf-8, ip_hostname=localhost, timestamp=1578329608525}]

Первые два коммита работают методом. Первый коммит работает, потому что принудительно используется GenericMessageConverter. А второй коммит просто показывает, что он правильно работает с интеграцией Spring 5.0.

Это обходной путь:

    @Bean(name = IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME)
    public static ConfigurableCompositeMessageConverter configurableCompositeMessageConverter(
            @Qualifier(IntegrationUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME) ConversionService conversionService) {
        return new ConfigurableCompositeMessageConverter(
                Collections.singleton(new GenericMessageConverter(conversionService)));
    }

Я неправильно использую приведение типов с потоком интеграции? У вас есть новое решение для приведения объекта в новой версии? Или это просто регрессия?

Заранее спасибо!

1 Ответ

1 голос
/ 06 января 2020

Итак, проблема действительно в том, что MappingJackson2MessageConverter пытается преобразовать Fact экземпляр в CatFact. Это происходит сразу после Http.outboundGateway() - ответ приходит с заголовком contentType как application/json. И этот действительно намек на то, чтобы MappingJackson2MessageConverter попытался преобразовать один объект в другой.

Когда я делаю это в вашем потоке:

            .transform(Message.class, m -> {
                Facts facts = (Facts) m.getPayload();
                int num = (int) m.getHeaders().get("NUM");
                return facts.getAll().get(num);
            })
            .headerFilter(MessageHeaders.CONTENT_TYPE)
            .transform(CatFact.class, id -> id)

(обратите внимание на headerFilter()), он возвращается в рабочее состояние с GenericMessageConverter.

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

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