Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.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/6/multithreading/4.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
Spring AMQP RabbitMQ InboundChannelAdapter和OutboundEndpoint不同的序列化/反序列化策略_Spring_Spring Integration_Spring Amqp_Spring Rabbit - Fatal编程技术网

Spring AMQP RabbitMQ InboundChannelAdapter和OutboundEndpoint不同的序列化/反序列化策略

Spring AMQP RabbitMQ InboundChannelAdapter和OutboundEndpoint不同的序列化/反序列化策略,spring,spring-integration,spring-amqp,spring-rabbit,Spring,Spring Integration,Spring Amqp,Spring Rabbit,我有一门课: public类SomeClass实现可序列化{ 私有字符串名称; 公共静态SomeClass值(字符串值){ //这里验证并返回SomeClass } } 它的序列化程序/反序列化程序: 公共类SomeClassSerializer扩展JsonSerializer{ @凌驾 公共void序列化(SomeClass SomeClass、JsonGenerator生成器、SerializerProvider提供程序)引发IOException{ generator.writeStri

我有一门课:

public类SomeClass实现可序列化{
私有字符串名称;
公共静态SomeClass值(字符串值){
//这里验证并返回SomeClass
}
}
它的序列化程序/反序列化程序:

公共类SomeClassSerializer扩展JsonSerializer{
@凌驾
公共void序列化(SomeClass SomeClass、JsonGenerator生成器、SerializerProvider提供程序)引发IOException{
generator.writeString(someClass.getName());
}
}
公共类SomeClassDeserializer扩展JsonDeserializer{
@凌驾
公共SomeClass反序列化(JsonParser解析器,反序列化上下文)引发IOException{
最终字符串名称=((TextNode)parser.getCodec().readTree(parser)).textValue();
返回SomeClass.valueOf(name);
}
}
在my
Jackson2ObjectMapperBuilder
配置中:

builder.serializerByType(SomeClass.class,新的SomeClassSerializer());
反序列化器ByType(SomeClass.class,新的SomeClassDeserializer());
SomeClass
位于
POST
/
GET
请求的主体中时,一切都会顺利进行。但是,通过Spring集成,我有:

返回Amqp
.内置适配器(容器)
.outputChannel(someClassChannel)
.messageConverter(新的Jackson2JsonMessageConverter(objectMapperBuilder.build()))
.get();
至于离港旅客:

@ServiceActivator(inputChannel=“someChannel”)
公共AMQOutboundEndpoint someOutboundEndpoint(RabbitTemplate RabbitTemplate,
FanoutExchange(交换机){
返回Amqp
.outboundAdapter(rabbitTemplate)
.exchangeName(exchange.getName())
.get();
}
使用my
RabbitTemplate
config:

@Bean
公共RabbitTemplate RabbitTemplate(Jackson2对象映射生成器对象映射生成器){
最终RabbitTemplate RabbitTemplate=新RabbitTemplate(连接工厂);
rabbitTemplate.setMessageConverter(新Jackson2JsonMessageConverter(objectMapperBuilder
.serializerByType(SomeClass.class,新的SomeClassSerializer())
.build());
返回兔模板;
}
和我的
网关

网关(requestChannel=“someChannel”) void publishEvent(@Header(value=“someClass”)someClass-someClass,@Payload-Object-Payload); 当我发送消息时,我在调用
SomeClass
valueOf
方法
SomeClass
(我抛出
InvalidArgumentException
)的
SomeClassDeserializer中遇到异常:

完整堆栈跟踪:

org.springframework.messaging.MessageHandlingException: error occurred during processing message in 'MethodInvokingMessageProcessor' [org.springframework.integration.handler.MethodInvokingMessageProcessor@43a251c4]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.messaging.handler.annotation.Header com.company.project.domain.package.SomeClass] for value 'com.company.project.domain.package.SomeClass@ec7887e4'; nested exception is java.lang.IllegalArgumentException: Couldn't convert value : com.company.project.domain.package.SomeClass@ec7887e4 into a valid com.company.project.domain.package.SomeClass object, failedMessage=GenericMessage [payload=com.company.project.security.domain.client.Client@55095ce3, headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedExchange=com.company, amqp_deliveryTag=1, amqp_consumerQueue=com.company.web.192.168.1.34, amqp_redelivered=false, amqp_contentEncoding=UTF-8, json__TypeId__=com.company.project.security.domain.client.Client, amqp_timestamp=Fri Oct 30 12:13:00 EET 2020, amqp_messageId=1dffe404-2235-4f79-4a14-315c896c3c4e, id=bcaa71d5-b454-e65c-6939-b9f07b7cc47b, event=com.company.project.domain.package.SomeClass@ec7887e4, amqp_consumerTag=amq.ctag-ImFjO9LBGoks9Lm3E0EkbQ, contentType=application/json, __TypeId__=com.company.project.security.domain.client.Client, timestamp=1604049180277}]
    at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:191)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:111)
    at org.springframework.integration.handler.ServiceActivatingHandler.handleRequestMessage(ServiceActivatingHandler.java:95)
    at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:127)
    at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:170)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.invokeHandler(BroadcastingDispatcher.java:224)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher.access$000(BroadcastingDispatcher.java:56)
    at org.springframework.integration.dispatcher.BroadcastingDispatcher$1.run(BroadcastingDispatcher.java:204)
    at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:57)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.messaging.handler.annotation.Header com.company.project.domain.package.SomeClass] for value 'com.company.project.domain.package.SomeClass@ec7887e4'; nested exception is java.lang.IllegalArgumentException: Couldn't convert value : com.company.project.domain.package.SomeClass@ec7887e4 into a valid com.company.project.domain.package.SomeClass object
    at org.springframework.core.convert.support.ObjectToObjectConverter.convert(ObjectToObjectConverter.java:112)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:191)
    at org.springframework.messaging.handler.annotation.support.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:111)
    at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:117)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:148)
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:116)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper$HandlerMethod.invoke(MessagingMethodInvokerHelper.java:1096)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.invokeHandlerMethod(MessagingMethodInvokerHelper.java:580)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:476)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:355)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:108)
    ... 10 more
Caused by: java.lang.IllegalArgumentException: Couldn't convert value : com.company.project.domain.package.SomeClass@ec7887e4 into a valid com.company.project.domain.package.SomeClass object
    at com.company.project.domain.package.SomeClass.valueOf(SomeClass.java:148)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.core.convert.support.ObjectToObjectConverter.convert(ObjectToObjectConverter.java:102)
通过尝试使用
valueOf
方法反序列化
SomeClass
,我发现反序列化程序使用的是正确的反序列化程序。但是,它试图反序列化的值是,
com.company.project。SomeClass@ec7887e4
不是我提供的序列化程序的结果(尽管我在
rabbitmplate
配置中向
Jackson2ObjectMapperBuilder
提供了所需的序列化程序)。可能是虫子,或者我做错了什么

更新:

下面是另一个意外行为:

我已临时将
SomeClassDeserializer
切换到:

公共类SomeClassDeserializer扩展JsonDeserializer{
@凌驾
公共SomeClass反序列化(JsonParser解析器,反序列化上下文)引发IOException{
最终字符串名称=((TextNode)parser.getCodec().readTree(parser)).textValue();
返回新的SomeClass(名称);
}
}
SomeClass
上的
valueOf
方法一直在调用,而不是新
SomeClass反序列化器上的
newsomeclass(name)
。此时,我将静态方法的名称从
valueOf
切换到
valueOfName
我的实际新实现开始被调用

由于没有对
SomeClass
的构造函数进行验证,因此出现了异常,尽管这次它开始反序列化为

newsomeclass(“com.company.project.domain.package。SomeClass@ec7887e4")
而不是

newsomeclass(“myActualValue”)
无法转换值:com.company.project.domain.package。SomeClass@ec7887e4进入有效的com.company.project.domain.package.SomeClass

看起来我们只是将类名作为字符串发送

com.company.project.domain.package。SomeClass@ec7887e4

这是
对象上的默认
toString()
实现

i、 e.
SomeClass.getName()
而不是
SomeClass.getName()
(假设类上有一个
getName()
方法)

编辑

对不起,我没注意到是头球

消息转换器仅对有效负载执行转换

对于头文件,您需要实现一个自定义的
HeaderMapper
——Spring只是将头文件传递给amqp客户机,而amqp客户机对它不知道的类型执行
toString()


子类化
DefaultAmqpHeaderMapper
并覆盖出站端的
populateUserDefinedHeader
,以及入站端的
extractUserDefinedHeaders

显示完整堆栈跟踪。@GaryRussell更新了问题。@GaryRussell我添加了另一个我不期望的行为,如果有帮助的话。谢谢。Tha这是我的观点。
SomeClassSerializer
不应该被使用吗,就像我的
SomeClassDeserializer
被使用一样?或者,我的反序列化器没有被使用,而只是带有
SomeClass(字符串名)的构造函数吗正在调用
,即不支持对
@标头
进行自定义序列化/反序列化