2
votes

What is the best way to do validation in Spring Integration. For example if we have an inbound gateway, when a message is received we want to validate it. If it's not valid -> return the validation errors to the gateway, else -> proceed with the normal flow of the application(transform, handle ...).

I tried a filter:

        @Bean
        public IntegrationFlow flow() {
            return IntegrationFlows.from(requestChannel())
                    .transform(new MapToObjectTransformer(Campaign.class))
                    .filter(Campaign.class, 
                            c -> c.getId() > 10 ? true : false, //if id > 10 then it's valid
                            e -> e.discardChannel(validationError()))
                    .handle(new MyHandler())
                    .get();
        }

        @Bean
        public IntegrationFlow validationErrorFlow() {
            return IntegrationFlows.from(validationError())
                    .handle(new ValidationHandler())//construct a message with the validation errors
                    .get();
        }

It works, but that way if I use a spring validator then i have to call it twice, in the filter and in the ValidationHandler (can be a transformer) to get the errors.

Any better way?

1

1 Answers

2
votes
.handle(new ValidationHandler())

You don't really need to create a new handler for each error.

In your filter, if the validation fails, throw MyValidationException(errors).

In the error flow on the gateway's error channel, the ErrorMessage has a payload that is a MessagingException with the MyValidatationException as its cause, and the failedMessage.

Something like...

.handle(validationErrorHandler())

...

@Bean
public MessageHandler validationErrorHandler() {
    return new AbstractReplyProducingMessageHandler() {
        public Object handleRequestMessage(Message<?> error) {
            MyValidationException myEx = (MyValidationException) 
                  ((ErrorMessage) error).getPayload.getCause();
            Errors errors = myEx.getErrors();
            ...
        }
    }
}

Or you can use a POJO messageHandler

public Object handle(MessagingException e) {
    ...
}