【发布时间】:2020-05-27 14:23:39
【问题描述】:
我们有一个应用程序,我们正试图从仅使用 Axon 框架转变为也使用 Axon 服务器。我们遇到了一个问题,即作为一种类型的多个实例的查询响应无法正确传输。不使用服务器时,不会发生如下详述的问题。
我们正在发送一个查询并期望一个特定类型的列表作为响应。
queryGateway.query(new MyQuery(...), ResponseTypes.multipleInstancesOf(MyResponse.class));
// elsewhere
@QueryHandler
public List<MyResponse> handle(MyQueryquery) {
return List.of(new MyResponse(...));
}
在没有服务器的情况下运行时效果很好。有意思的是MultipleInstancesResponseType#convert(Object)被调用了一次,参数就是List<MyResponse>实例。这里不需要转换。
当与服务器一起运行时,MultipleInstancesResponseType#convert(Object) 被调用了两次。第一次,如上,参数是预期的List<MyResponse>,同样,不需要转换。但是,随后再次调用MultipleInstancesResponseType#convert(Object),参数为List<LinkedHashMap>。这需要转换,但失败了,因为List<MyResponse>无法转换为List<MyResponse>。
我在调试器中看到了两个 convert 调用,因为在我的测试中,同一个 JVM 正在创建和处理查询。
我相信正在发生的事情是查询处理程序正在返回List<MyResponse>,并且框架正在正常调用MultipleInstancesResponseType#convert(Object)。然后响应被序列化(gRPC?)并发送到服务器,然后服务器将响应发送给原始调用者。然后,原始调用者尝试转换有效负载,但失败了。所以,在 gRPC 序列化/反序列化过程的某个地方,一些类型信息已经丢失。
最终结果是原始调用者得到一个IllegalArgumentException 声明
检索到的响应 [class java.util.ArrayList] 不能转换为预期响应类型 [class MyResponse] 的列表
在GrpcPayloadSerializer 上设置断点表明响应负载在被序列化以发送到服务器时正确地是List<MyResponse>。
documentation 似乎清楚地表明List<of-something> 是受支持的查询处理程序返回类型。
【问题讨论】: