我正在使用Spring上的消息传递,我有一个简单的问题。
当另一个服务发送一条消息,要求提供一个对于能够应答的服务不存在的信息时,我第一件事是通过“null”来执行有效负载:
MyResponse myResponse = service.find(id); //ops, the information with this id does not exists
Message<MyResponse> message = MessageBuilder
.withPayload(myResponse) // the information does not exists, so null
.copyHeadersIfAbsent(request.getHeaders())
.build();
但方法withPayload
不接受null。那么,用原始请求的“空”值填充此消息的良好做法或替代方法是什么,接收结果并知道此信息不存在?
现在我将一个空对象(new MyResponse()
)传递给有效负载,但这可能会造成消费者消息的混乱。我可以创建另一个类来表示这个“不存在”状态,但我现在正试图理解我的选择。
谢谢!
答案 0 :(得分:1)
null
有效负载不会带来太多信息,并且不受许多网络协议的支持。此外,框架中有许多基于有效负载类型的位置,但如果它是null
,我们可能没有任何信息是什么以及如何处理它。在某些组件中,null
返回值是一个停止流的信号,并且不会在下游生成任何消息来回复。
您可以使用的解决方案就像常量对象(MyNullResponse
)一样,表明它是null
。
您可能还会考虑使用异常而不是尝试返回null的方法。让我们考虑你做一些搜索后处理和一堆过滤和转换步骤。在null
的情况下,您的消息仍将继续传输。但是当我们处理异常时(就像它与javax.persistence.EntityNotFoundException
一样),我们只是立即将问题告诉最终用户。而这已经是目标服务的责任,将该异常表示为最终用户可理解的消息。
我们有一个关于null payload support
的{{3}}。你可以在那里阅读更多的理由以及其他人对此事的看法。我想在这个问题上允许的事情就像Optional.empty()
。然后,我们可以在目标最终用户代码上轻松将其映射到null
。
答案 1 :(得分:0)
您必须明确区分响应本身(在您的情况下为MyResponse对象)和是否存在与您的业务逻辑相关的信息,您构造的消息必须尽可能通用而不是硬连接到您的服务层,简单原因=&gt;消息只是您发送给消费者的消息,因此如果可能的话,尝试在您的对象MyResponse(布尔标志)中嵌入是否存在信息,并在调用您的服务后即时构建它 而不是
MyResponse myResponse = service.find(id);
你可以试试这个:
CustomResponse myResponse = service.find(id);
// use helper class to respect DRY principal if you need it somewhere
MyResponse messageReponse = ResponseBuilder.constructResponse(myReponse);
Message<MyResponse> message =// .. construct you message
在上面的示例中,如果为null,则ResponseBuilder会处理myResponse,并完全创建响应(您可以集成所有情况..)
答案 2 :(得分:0)
我想在阅读@Artem answer之后与大家分享我的解决方案。
我创建了一个OptionalMessage
类,与Java 8+中的Optional
类非常相似。我正在使用application/json
作为content-type
来发送消息。
我可以在不同的消息中使用此OptionalMessage
:
OptionalMessage optionalMessage = messaging.find(id);
if (optionalMessage.isPresent()) {
MyMessage myMessage = optionalMessage.getContent();
}
它还有方法of()
和empty()
,在另一方用来填充OptionalMessage
。
生成的Json结构遵循以下示例:
{
"content": { /*attributes */}
}
当我们没有内容(我的&#34; null&#34;返回)时,Json看起来像这样:
{
"content": null
}
我尝试使用泛型(OptionalMessage<MyMessage>
),但我需要更改my Jackson setup(在IntegrationFlow DSL上),以便在调用java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to MyMessage
时不会收到错误getContent
方法