如何返回Message(来自Spring)来表示未找到信息?

时间:2018-01-31 16:07:04

标签: spring messaging spring-cloud-stream

我正在使用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())传递给有效负载,但这可能会造成消费者消息的混乱。我可以创建另一个类来表示这个“不存在”状态,但我现在正试图理解我的选择。

谢谢!

3 个答案:

答案 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方法