我将我的 Spring 启动版本从2.1.8.RELEASE
升级到2.2.2.RELEASE
(因此 Spring 集成从5.1
升级到5.2.2.RELEASE
(,如果我们在符合条件的弹簧转换器中有一个杰克逊转换器,带有@IntegrationConverter
的自动转换似乎不再起作用。
转换器会自动声明,因为我有一个依赖项jackson-databind
在我的项目依赖项中声明。我需要杰克逊,因为我必须将从HTTP请求收到的有效负载转换为java bean。但是因为这个转换器是声明的,所以使用它代替 Spring 集成GenericMessageConverter
并且它无法转换,因为它首先尝试在 bean 上调用toString()
,然后转换toString()
对象表示。
我在 github 的主机中有一个示例:https://github.com/Kruschenstein/spring-integration-playground .这是一个简单的 Spring 集成流程,我们在其中运行一个服务器,该服务器根据用户输入询问 HTTP API。典型的应用程序用途是运行一个telnet localhost 1234
输入一个介于0
和255
之间的数字,并且有关 cat 的事实将显示在用户终端中。
这是我从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)));
}
我是否错误地将类型转换与集成流一起使用?您是否有使用新版本转换对象的新解决方案?或者这只是一种回归?
提前感谢!
因此,问题确实出在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
回到工作状态。
这不是错误或回归。这只是标头和有效负载之间状态不一致的事实。不过,我们可能需要考虑如何减轻它...随意提出一些想法的GH问题。