首页 > 解决方案 > 使用 spring-integration 5.1.3.RELEASE 时过滤器上的 MessageHandlingException

问题描述

所以我正在尝试运行一个通过以下流程运行的测试:

@EnableBinding({Sink.class,Source.class})
public class MyFlow {
public @Bean IntegrationFlow myIntegrationFlow() {
  return IntegrationFlows.from("input") //
  .transform(new JsonToObjectTransformer()) //
  .filter(new MessageDroolsFilter())
  .........
  get();
}

 public class MessageDroolsFilter implements MessageSelector {

   @Override
   public boolean accept(Message<?> message) {
     return true;
   }

 }
}

所以在spring-integration-core-5.1.2.RELEASE一切运行良好。我想升级到5.1.3.RELEASE,我得到以下异常。我不明白为什么它会影响流量。

org.springframework.messaging.MessageHandlingException:
 nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1004E:
 Method call: Method accept(com.example.MyClass) 
cannot be found on type com.example.myIntegrationFlow$$Lambda$942/1009480482, failedMessage=GenericMessage
[payload=com.example.MyClasst@72bd8702[id=100, timestamp=1563801840597}]
        at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:109)
    at org.springframework.integration.filter.AbstractMessageProcessingSelector.accept(AbstractMessageProcessingSelector.java:62)
    at org.springframework.integration.router.RecipientListRouter$Recipient.accept(RecipientListRouter.java:320)
    at org.springframework.integration.router.RecipientListRouter.lambda$determineTargetChannels$0(RecipientListRouter.java:258)
    at java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)

编辑:

我有一个路由器,我希望根据接收到的对象类型路由消息。

private IntegrationFlow messagesFlow() {
  return sf -> sf //
      .routeToRecipients(routeMessages());
} 


private Consumer<RecipientListRouterSpec> routeMessages() {
  return sf -> sf
      .recipientFlow(new GenericSelector<MyObject1>() {

      @Override
      public boolean accept(MyObject1 source) {
        return source instanceof MyObject1;
      }},
        f -> f.transform(myTransformer)
              .filter(new DiscardHeaderMessageFilter()) 
              .handle(myHandler))
    .recipientFlow(new GenericSelector<MyObject2>() {
      @Override
      public boolean accept(MyObject2 source) {
        return source instanceof MyObject2;
      }
    }
    .defaultOutputChannel(DISCARD_CHANNEL);
}

我仍然得到同样的错误:

Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1004E: Method call: Method accept(com.example.MyObject1) cannot be found on type com.example.MyFlow$2
    at org.springframework.expression.spel.ast.MethodReference.findAccessorForMethod(MethodReference.java:225)
    at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:134)
    at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:54)
    at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:390)
    at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:90)
    at org.springframework.expression.spel.ast.SpelNodeImpl.getTypedValue(SpelNodeImpl.java:114)
    at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:365)
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:172)
    at org.springframework.integration.util.AbstractExpressionEvaluator.evaluateExpression(AbstractExpressionEvaluator.java:160)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.invokeExpression(MessagingMethodInvokerHelper.java:664)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.invokeHandlerMethod(MessagingMethodInvokerHelper.java:655)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.processInternal(MessagingMethodInvokerHelper.java:491)
    at org.springframework.integration.handler.support.MessagingMethodInvokerHelper.process(MessagingMethodInvokerHelper.java:362)
    at org.springframework.integration.handler.MethodInvokingMessageProcessor.processMessage(MethodInvokingMessageProcessor.java:106)

标签: springspring-integration

解决方案


看起来您的问题与提到的.filter().

仔细查看堆栈跟踪:

at org.springframework.integration.filter.AbstractMessageProcessingSelector.accept(AbstractMessageProcessingSelector.java:62)
at org.springframework.integration.router.RecipientListRouter$Recipient.accept(RecipientListRouter.java:320)

所以,你有一个routeToRecipients()地方,其中一个recipient()不符合期望。

更新

该错误是意料之中的:收件人列表路由器针对当前消息与每个收件人进行协商。当您的消息是MyObject1时,第一个.recipientFlow(new GenericSelector<MyObject1>(), 运行良好,因为它的方法签名与您调用它的对象兼容。但是当同样MyObject1到达第二个时.recipientFlow(new GenericSelector<MyObject2>()--,它不能调用它,因为不兼容的类型。

完全不清楚为什么source instanceof MyObject1;当参数完全是MyObject1......

我会说签名必须是这样的:

.recipientFlow(new GenericSelector<Object>() {

  @Override
  public boolean accept(Object source) {
    return source instanceof MyObject1;
  }}

我的意思是Object与发送的任何有效负载兼容的泛型类型。完全不清楚为什么您的 IDE 没有告诉您这是多余的,因为在调用此方法时source instanceof MyObject2它总是如此。true只有当我们通过反射调用它时,这个方法对任何其他类型都失败了,就像在 SpEL 的情况下一样。


推荐阅读