【问题标题】:Splitter returning empty array list spring integration拆分器返回空数组列表弹簧集成
【发布时间】:2014-12-15 11:40:19
【问题描述】:

我们有一个案例,在我们的 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)

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

问候, 米琳达

【问题讨论】:

    标签: java spring arraylist spring-integration enterprise-integration


    【解决方案1】:

    好吧,你可以用&lt;request-handler-advice-chain&gt; 来克服它,&lt;splitter&gt; 当然还有一些自定义的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 的原因是什么,因为拆分器总是会产生多条消息,并且对您隐藏了迭代逻辑。

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

    没有可用的输出通道或回复通道标头

    你真的应该这样做:

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

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

    【讨论】:

    • 嗨,Artem,您是否也可以为上述示例提供一个 xml 配置示例,特别是它显示了如何将给定的 MessageChannel 从 xml 配置设置为 MessagingTemplate,谢谢跨度>
    • EmptyListRequestHandlerAdvice添加了XML配置
    • 嗨,artem,这也可能有点跑题了,但是在拆分器中从数据库本身加载数据然后在那里执行拆分逻辑是否合乎逻辑,或者是加载数据的最佳实践在服务中,并将其传递给服务进行拆分和发送
    • 其实没有限制。由于这是您的代码,即使您在此处使用 POJO 方法调用,您也不会对 EIP 模式产生任何影响,有时最好在一个地方执行此操作,而不是将其分成几个步骤。我最近添加了JdbcSplitter 示例:github.com/spring-projects/spring-integration-extensions/pull/…
    • 您好 Artem,有两个新问题,其中一个是拦截器问题。这两个问题已在主要问题更新部分列出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多