春季通道拦截器 – 如何在不抛出错误的情况下返回空消息

huangapple go评论69阅读模式
英文:

Spring Channel Interceptor - how to return null message without throwing an error

问题

上下文: 我有一个消息通道,它执行对服务A的POST请求,并有两个拦截器 - 一个用于进行一些处理,另一个用于发送到另一个服务B。

问题: 在哪里添加一个功能开关,以便我可以停止发送给A,但仍然发送给B?(还有第一个拦截器在发送给B之前需要进行一些处理)

我的方法是在第二个拦截器中添加功能开关,并返回一个空的消息对象,以便messageChannel.send不会被执行。这种方法有效,但会引发一个不希望出现的错误。

根据spring的消息通道文档

在拦截器的preSend方法在消息实际发送到通道之前被调用。这允许在必要时修改消息。如果此方法返回null,则实际的发送调用将不会发生。

是否有一种方式可以在不引发错误的情况下静默地终止发送过程,或者是否有更好的方法?

英文:

The context: I have a message channel that does a post request to a service A and 2 interceptors - one that does some processing and another one that sends to another service B.

The problem: Where to add a feature toggle such that I can stop sending to A but still send to B? (also 1st interceptor does some processing that is needed before sending to B)

My approach was to add the feature toggle in the 2nd interceptor and return a null message object so that the messageChannel.send won't be executed. This works but also throws an error which is not desirable.

According to spring's message channel documentation:

> The preSend of an interceptor is invoked before the Message is
> actually sent to the channel. This allows for modification of the
> Message if necessary. If this method returns {@code null} then the
> actual send invocation will not occur.

Is there a way to silently kill the sending process or would there be a better approach?

答案1

得分: 1

不使用ChannelInterceptor,尝试使用Filter

消息过滤器用于根据某些条件(例如消息头值或消息内容)决定是否应传递消息或丢弃消息。

通过使用过滤器,您可以指定自己的MessageSelector实现,当MessageSelector返回false时,过滤器将丢弃消息。

package exampleCode;

import org.springframework.integration.core.MessageSelector;
import org.springframework.messaging.Message;

public class MySelector implements MessageSelector {

    @Override
    public boolean accept(Message<?> message) {
        // 如果消息应该继续通过过滤器,请返回true

        // 如果消息应该被阻止继续,请返回false
    }
}

然后,您可以配置您的选择器用于过滤器

<bean id="MySelector" class="exampleCode.MySelector" />

<int:filter input-channel="someChannel" ref="MySelector"
    output-channel="someOtherChannel" />
英文:

Instead of using a ChannelInterceptor, try a Filter

> Message filters are used to decide whether a Message should be passed along or dropped based on some criteria, such as a message header value or message content itself.

With a Filter you can specify your own implementation of a MessageSelector, which when returning false, will cause the Filter to discard the message.

package exampleCode;

import org.springframework.integration.core.MessageSelector;
import org.springframework.messaging.Message;

public class MySelector implements MessageSelector {

    @Override
    public boolean accept(Message&lt;?&gt; message) {
        // If the message should continue through the filter, return true

        // If the message should be blocked from continuing, return false
    }
}

Then you can configure your selector to be used by a filter

&lt;bean id=&quot;MySelector&quot; class=&quot;exampleCode.MySelector&quot; /&gt;

&lt;int:filter input-channel=&quot;someChannel&quot; ref=&quot;MySelector&quot;
	output-channel=&quot;someOtherChannel&quot; /&gt;

答案2

得分: 0

在3.0版本之前,在没有订阅者的PublishSubscribeChannel上调用send方法会返回false。当与MessagingTemplate一起使用时,会抛出MessageDeliveryException。从3.0版本开始,行为已更改,即如果至少有最低订阅者存在(并成功处理消息),则始终认为发送成功。可以通过设置minSubscribers属性来修改此行为,默认为0。

参考:https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/messaging-channels-section.html

此外,我认为您可以使用@Spring的@Conditional来实现Spring中的条件变量,以便根据给定条件执行拦截器。

参考:https://javapapers.com/spring/spring-conditional-annotation/#:~:text=Spring%20Boot%20module%20makes%20heavy,variables%2C%20irrespective%20of%20its%20value.

英文:

Prior to version 3.0, invoking the send method on a PublishSubscribeChannel that had no subscribers returned false. When used in conjunction with a MessagingTemplate, a MessageDeliveryException was thrown. Starting with version 3.0, the behavior has changed such that a send is always considered successful if at least the minimum subscribers are present (and successfully handle the message). This behavior can be modified by setting the minSubscribers property, which defaults to 0.

Reference: https://docs.spring.io/spring-integration/docs/5.0.5.RELEASE/reference/html/messaging-channels-section.html

Also, I think you can implement Conditional Variables with Spring using @Conditional for the interceptors to execute for a given condition.

Reference: https://javapapers.com/spring/spring-conditional-annotation/#:~:text=Spring%20Boot%20module%20makes%20heavy,variables%2C%20irrespective%20of%20its%20value.

huangapple
  • 本文由 发表于 2020年8月14日 22:31:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63414780.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定