4

我们有一个案例,在我们的 Spring 集成拆分器逻辑中,它可以返回一个空值,ArrayList因此不提供要路由的数据。ArrayList当分离器返回空时,我们应该如何处理这种情况并将其重新路由到不同的通道。

更新 :

如 Artem 所示,我创建了一个自定义建议并成功完成了重新路由,但是仍然存在两个问题,其中第二个描述的是列出的阻止程序问题

我目前的课程如下

public class EmptyListRequestHandlerAdvice extends AbstractRequestHandlerAdvice {

    private final MessagingTemplate messagingTemplate = new MessagingTemplate();

    public EmptyListRequestHandlerAdvice(MessageChannel emptyListChannel) {
        this.messagingTemplate.setDefaultChannel(emptyListChannel);
    }

    @Override
    protected Object doInvoke(ExecutionCallback callback, Object target,
            Message<?> message) throws Exception {
        Object result = callback.execute();

        if (result==null) {
            this.messagingTemplate.convertAndSend(new ArrayList<InventoryHotel>());
        }

        return result;
    }

每当拆分器返回一个新的空数组列表时,“callback.execute() 的结果为空。但是,只要从拆分器返回的数组列表不为空,则返回的结果类型为 org.springframework.integration.util.FunctionIterator 而不是集合类型。关于是否有可能在两种情况下都返回集合而不是 null 或函数迭代器?至少避免获取函数迭代器并获取数组列表。

此外,当为构造函数设置有效的通道名称并通过该通道将消息发送到转换器方法时,转换器方法已成功执行,但是当它返回值时会发生以下错误

org.springframework.messaging.MessagingException: org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available
    at org.springframework.integration.dispatcher.AbstractDispatcher.wrapExceptionIfNecessary(AbstractDispatcher.java:133)
    at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:120)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:101)
    at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:97)
    at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:77)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:255)

关于为什么会发生这种情况以及如何解决它的任何建议。

问候, 米琳达

4

1 回答 1

2

<request-handler-advice-chain>好吧,你可以用for the<splitter>当然还有一些 custom来克服它AbstractRequestHandlerAdvice

public class EmptyListRequestHandlerAdvice extends AbstractRequestHandlerAdvice {

    private final MessagingTemplate messagingTemplate = new MessagingTemplate();

    public EmptyListRequestHandlerAdvice(MessageChannel emptyListChannel) {
         this.messagingTemplate.setDefaultChannel(emptyListChannel);
    }

    @Override
    protected Object doInvoke(ExecutionCallback callback, Object target, Message<?> message) throws Exception {
          Collection<?> result = (Collection<?>) callback.execute();
          if (result.isEmpty) {
             this.messagingTemplate.convertAndSend(result);
          }
          return result;
     }

} 

更新

拥有该类,您可以像这样使用它:

<splitter>
  <request-handler-advice-chain>
      <beans:bean class="com.my.proj.int.EmptyListRequestHandlerAdvice">
          <beans:constructor-arg ref="emptyListChannel"/>
      </beans:bean>
  </request-handler-advice-chain>
</splitter>

<channel id="emptyListChannel"/>

更新2

关于是否有可能在两种情况下都返回一个集合而不是 null 或函数迭代器的任何想法?

不,这是不可能的。它是拆分器的内部逻辑,因此它handleRequestMessage产生Iterator一个streaming拆分过程增益。目前尚不清楚您拥有的原因是什么Collection,因为拆分器总是会产生多条消息,并且对您隐藏了迭代逻辑。

从您的第一个要求开始,您要求解决方案将一个空列表发送到不同的频道。所以,我不明白为什么迭代器逻辑会影响你。

没有可用的 output-channel 或 replyChannel 标头

你真的应该这样做:

this.messagingTemplate.send(MessageBuilder.withPayload(new ArrayList<InventoryHotel>())
      .copyHeaders(message.getHeaders().build());

拥有基于该 requestMessage 的新消息,您将复制其所有标头,因此replyChannel标头也在那里。

于 2014-10-20T13:26:24.173 回答