1

i am trying to convert below XML snippet into Java version, appreciate any help here

<int:router input-channel="channel_in" default-output-channel="channel_default" 
  expression="payload.name" ignore-channel-name-resolution-failures="true">
    <int:mapping value="foo" channel="channel_one" />
    <int:mapping value="bar" channel="channel_two" />
</int:router>

Here is what i did for my concrete example

@Router(inputChannel = "routerChannel")
    public String route(Account message) {
        if (message.getType().equals("check")) {
            return "checkChannel";
        } else if (message.getType().equals("credit")) {
            return "creditChannel";
        } 
        return "errorChannel";
}

@Bean
public DirectChannel checkChannel() {
    return new DirectChannel();
}

when i do above i am seeing below error

org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:8090.checkChannel'.;

1 Answer 1

1

All the Spring Integration custom tag has a description like this:

<xsd:element name="router" type="routerType">
    <xsd:annotation>
        <xsd:documentation>
            Defines a Consumer Endpoint for the
            'org.springframework.integration.router.AbstractMessageProcessingRouter' implementation
            that serves as an adapter for invoking a method on any
            Spring-managed object as specified by the "ref" and "method" attributes.
        </xsd:documentation>
    </xsd:annotation>
</xsd:element>

So, it becomes pretty clear that we need some AbstractMessageProcessingRouter implementation to be present in the Java Configuration.

Also we have a paragraph in the Reference Manual like this:

With XML configuration and Spring Integration Namespace support, the XML Parsers hide how target beans are declared and wired together. For Java & Annotation Configuration, it is important to understand the Framework API for target end-user applications.

According your expression="payload.name" we need to look for the ExpressionEvaluatingRouter and then also read a chapter about @Bean configuration:

    @Bean
    @Router(inputChannel = "channel_in")
    public ExpressionEvaluatingRouter expressionRouter() {
        ExpressionEvaluatingRouter router = new ExpressionEvaluatingRouter("payload.name");
        router.setDefaultOutputChannelName("channel_default");
        router.setChannelMapping("foo", "channel_one");
        router.setChannelMapping("bar", "channel_two");
        return router;
    }
Sign up to request clarification or add additional context in comments.

5 Comments

thank you, how do i handle this router based on an attribute value of an object, i have a Account object in which based on the type of object i should be able to route it to respective channels, also how do i define DirectChannel using java
Well, you still continue to use the SpEL against that Account payload. The DirectChannel has to be declared as a @Bean. Please, bear in mind that Spring Integration is just a Spring Framework extension for EIP, but it is still Spring, therefore everything is a bean and you should follow existing Java & Annotation rules to declare Spring Integration components.
Good, but do you really have a @EnableIntegration on some @Configuration class? docs.spring.io/spring-integration/docs/current/reference/html/…
Good. So, you route a check message to the checkChannel, but is there anything who consumes this channel, e.g. @ServiceActivator? Maybe it's time for you to come back to documentation to understand how Spring Integration works?
yes i have that but there was a spell issue on the Service Activator channel definition, any ways thanks for guiding me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.