gpt4 book ai didi

spring-boot - 使用 Kotlin 观察参数类型不匹配的 Spring Amqp Remoting

转载 作者:行者123 更新时间:2023-12-02 13:38:33 26 4
gpt4 key购买 nike

虽然服务只有 1 个参数,但在将 spring 与 kotlin 组合使用时,我总是遇到参数不匹配。
我也调试过org.springframework.remoting.support.RemoteInvocation.invoke方法
我可以看到它正好传递了 1 个参数和正确的 targetObject。但是invoke(targetObject, this.arguments);导致参数不匹配。

源代码:

https://github.com/c-nnooka/RabbitMqRemotingKotlin

异常(exception)

Caused by: **java.lang.Throwable: argument type mismatch**
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_161]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_161]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_161]
at org.springframework.remoting.support.RemoteInvocation.invoke(RemoteInvocation.java:215) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.remoting.support.DefaultRemoteInvocationExecutor.invoke(DefaultRemoteInvocationExecutor.java:39) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invoke(RemoteInvocationBasedExporter.java:78) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.remoting.support.RemoteInvocationBasedExporter.invokeAndCreateResult(RemoteInvocationBasedExporter.java:114) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.amqp.remoting.service.AmqpInvokerServiceExporter.onMessage(AmqpInvokerServiceExporter.java:80) ~[spring-amqp-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1457) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1348) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:785) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:769) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1010) ~[spring-rabbit-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at java.lang.Thread.run(Thread.java:748) ~[?:1.8.0_161]
at org.springframework.remoting.support.RemoteInvocationUtils.fillInClientStackTraceIfPossible(RemoteInvocationUtils.java:45) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.remoting.support.RemoteInvocationResult.recreate(RemoteInvocationResult.java:156) ~[spring-context-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.amqp.remoting.client.AmqpClientInterceptor.invoke(AmqpClientInterceptor.java:78) ~[spring-amqp-2.0.2.RELEASE.jar:2.0.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.0.4.RELEASE.jar:5.0.4.RELEASE]
at com.sun.proxy.$Proxy108.findJobById(Unknown Source) ~[?:?]

接口(interface)详情:
interface IJobQueryService{

fun findJobById(args : QueryJobArgs) : QueryJobResponse

}

interface IJobService : IJobQueryService

服务实现细节:
class JobController(val jobQueryService: IJobQueryService) : IJobService{


override fun findJobById(args: QueryJobArgs): QueryJobResponse {
return jobQueryService.findJobById(args)
}


}

bean 配置: (注意:为简单起见,未指定完整配置)
    @Bean
fun rmsExporter(rabbitTemplate: RabbitTemplate):AmqpInvokerServiceExporter {
val exporter = AmqpInvokerServiceExporter();
exporter.amqpTemplate = rabbitTemplate;
exporter.service = JobController(JobQueryProvider());
exporter.serviceInterface = IJobService::class.java
exporter.messageConverter = producerJackson2MessageConverter()
return exporter;
}

@Bean
fun rmxProxy(rabbitTemplate: RabbitTemplate) : AmqpProxyFactoryBean {
val proxy = AmqpProxyFactoryBean();
proxy.amqpTemplate = rabbitTemplate;
proxy.serviceInterface = IJobService::class.java
proxy.routingKey = "rms.webservice.api"
return proxy;
}

调用详情
val jobservice  = applicationContext.getBean(IJobService::class.java)

println("Remoting Is On => " + jobservice.findJobById(QueryJobArgs().apply { job = Job().apply { id = 1 } } ))

最佳答案

您尝试通过网络传输 JSON 的问题。

因此 AmqpClientInterceptor包裹你的QueryJobArgs进入RemoteInvocation对象,并且已经将其序列化为 JSON,例如:

(Body:'{"methodName":"findJobById","parameterTypes":["com.example.rabbiitmqremoting.args.job.QueryJobArgs"],"arguments":[{"job":{"id":1,"createdBy":null}}],"attributes":null}' MessageProperties [headers={__TypeId__=org.springframework.remoting.support.RemoteInvocation}, contentType=application/json, contentEncoding=UTF-8, contentLength=167, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])

关注 __TypeId__=org.springframework.remoting.support.RemoteInvocation标题。这个用于消费者端将内容反序列化为 RemoteInvocation .但由于 arguments 没有(自动)信息被反序列化为 QueryJobArgs他们仍然是 LinkedHashMap .因此 Caused by: java.lang.Throwable: argument type mismatch .

作为一种解决方法,我建议您返回 SimpleMessageConverter。它将使用标准的 Java 序列化机制。

更新

好的!你知道我也用 JSON 破解了这个。

所以,我这样做了:
@Autowired
lateinit var objectMapper: ObjectMapper

@PostConstruct
fun init() {
this.objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY)
}

并注入(inject)了这个 objectMapper进入所有 Jackson您的 RabbitConfig 中提供的转换器.现在它按预期工作,我假设:
Hellow From RMS
Remoting Is On => com.example.rabbiitmqremoting.response.QueryJobResponse@151bf776

我还删除了与 messageHandlerMethodFactory 相关的所有修改。 .看起来它不涉及 RPC。
但是,您可能需要它来处理其他一些事情。不同的故事虽然...

关于spring-boot - 使用 Kotlin 观察参数类型不匹配的 Spring Amqp Remoting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49813562/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com