Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring AMQP-Jackson2JsonMessageConverter设置_TypeId_uu,自版本2.1起,使用接口而不是具体类型 问题_Java_Spring_Spring Amqp - Fatal编程技术网

Java Spring AMQP-Jackson2JsonMessageConverter设置_TypeId_uu,自版本2.1起,使用接口而不是具体类型 问题

Java Spring AMQP-Jackson2JsonMessageConverter设置_TypeId_uu,自版本2.1起,使用接口而不是具体类型 问题,java,spring,spring-amqp,Java,Spring,Spring Amqp,我们已将Spring boot版本从2.0.5升级到2.1.8。 因此,Spring AMQP也从2.0.6升级到了2.1.8 此后,Jackson2JsonMessageConverter无法解析来自@RabbitListener注释方法的应答消息,因为它们返回一个接口(实际上在代码中声明为泛型)。此接口用于设置消息\u TypeId\u属性 在2.0版本中,它用于将TypeId设置为实际的混凝土类 我做了一些挖掘,下面是我对这个问题的理解(代码如下) 当带@RabbitListener注释的

我们已将Spring boot版本从2.0.5升级到2.1.8。
因此,Spring AMQP也从2.0.6升级到了2.1.8

此后,
Jackson2JsonMessageConverter
无法解析来自@RabbitListener注释方法的应答消息,因为它们返回一个接口(实际上在代码中声明为泛型)。此接口用于设置消息
\u TypeId\u
属性

在2.0版本中,它用于将TypeId设置为实际的混凝土类

我做了一些挖掘,下面是我对这个问题的理解(代码如下)

当带@RabbitListener注释的方法返回时,将调用
MessagingMessageListenerAdapter#onMessage
,并将结果封装在
InvocationResult
对象中,该对象包含
genericType
属性

这个
genericType
是从@RabbitListener注释的方法的返回类型设置的

然后,
Jackson2JsonMessageConverter#createMessage
方法使用它来设置
\u TypeId
属性

另一方面,
Jackson2JsonMessageConverter#fromMessage
可以使用此属性解析Json以找出实际的类型

问题是,由于引入了
InvocationResult
genericType
,我们用@RabbitListener注释的方法被声明为返回一个接口,因此
\u TypeId\u
属性是用接口而不是实际的具体类设置的。以下是来自
Jackson2JsonMessageConverter#fromMessage
(实际上来自
AbstractJackson2MessageConverter
)的代码位,该位已更改(除其他外):

if(getClassMapper()==null){
getJavaTypeMapper().fromJavaType(this.objectMapper.constructType(
genericType==null?objectToConvert.getClass():genericType),messageProperties);
}
否则{
getClassMapper().fromClass(objectToConvert.getClass(),messageProperties);//NOSONAR从不为null
}
由于genericType不为null并且包含interfaceType。。。你可以看到我们的麻烦

在版本2.1之前,我们没有添加任何问题,因为Jackson2JsonMessageConverter#createMessage()始终直接使用
objectToConvert.getClass()

if(getClassMapper()==null){
getJavaTypeMapper().fromJavaType(this.jsonObjectMapper.constructType(objectToConvert.getClass()),
信息属性);
}
否则{
getClassMapper().fromClass(objectToConvert.getClass(),
信息属性);
}
代码 这是我们的代码:


公共抽象类AWorker{
@RabbitListener(queues=“${rabbit.worker.queue}”
,errorHandler=“workerErrorHandler”
,returnExceptions=“true”)
public O receiveMessage(I inputMessage,@Header(LoggerUtil.LOGGER\u MDC\u ID)字符串mdcId,@Header(RabbitConstants.CONTEXT\u INFO\u Header\u KEY)字符串contextInfoStr){
if(requestdTofIrTimImplementation.class的inputMessage实例){
返回新的ResponseDtoFirstImplementation();
}否则{
返回新的ResponseDtoSecondImplementation();
}
}
}
当然,
receiveMessage
方法的内容得到了简化,关键是实际实现可以根据输入的具体类型返回不同的具体类型

可能的解决办法 我想有两种可能的解决方法,但没有一种是真正好的或易于维护的

第一种方法是使用
RemoteInvocationAwareMessageConverterAdapter
封装
Jackson2jsonMessageConverter
。 如果我这样做,就会调用
MessageConverter#toMessaget(Object-Object,MessageProperties-MessageProperties)
,而不是
MessageConverter#toMessage(Object-Object,MessageProperties-MessageProperties,@Nullable-Type-genericype)
,因此我们回到原来的方式。
但这听起来更像是一种黑客行为,而不是一个恰当的解决方案。如果
RemoteInvocationAwareMessageConverter
改变了它的行为,我们就回到了最初的问题

第二种方法是使用现有的类映射器,但即使它可以工作,维护起来也比较困难(特别是当涉及到trustedPackages时,如果我们有很多来自不同包的类需要序列化)。或者实现一个customClassMapper,这也增加了一些工作要做

由于它在2.1版之前工作正常,我不确定是否绝对有必要重新实现ClassMapper


但我找不到任何简单的方法来使用具体类型设置genericType,这似乎是一种回归,因为。请打开一个。谢谢@GaryRussell,我这样做了。这似乎是由于。请打开一个。谢谢@GaryRussell,我会的。