Search code examples
javaspring-integrationdslxml-validationspring-integration-dsl

Validator Spring integration


I'm trying to validate an incoming xml data in spring integration. I have used the Validator and implemented it's methods. But when I'm running the application i'm getting that the class is not supported. this is my code in the validator class:

@Override
    public boolean supports(Class<?> clazz) {
        return Document.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        try {
            classUtil.validateDocument((Document) target, someResult);
        } catch (Exception exc) {
            errors.reject(error);
        }
    }

and this is my integration flow :

return IntegrationFlows.from(
        Http.inboundGateway("/foo")
            .requestMapping(m -> m.methods(HttpMethod.POST)
                                  .consumes("application/xml")
            )
            .validator(new Validator())
    )
    .transform(new ByteArrayToDocumentClass())
    .transform(Transformers.objectToString())
    .enrichHeaders(h -> h.headerExpression(h, path))
    .get();

the error that I'm getting is :

SEVERE: Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.messaging.converter.MessageConversionException: Cannot create request message; nested exception is java.lang.IllegalArgumentException: Validator [class com.example.Validator] does not support [class [B]] with root cause
java.lang.IllegalArgumentException: Validator [class com.example.Validator] does not support [class [B]

is it the problem because i'm trying to validate in my flow before converting the incoming data to document ?


Solution

  • No, the validation phase is correct, but apparently the body of HTTP request is not converted to that Document. It looks like the body is still presented as byte[].

    I see that you have a logic like ByteArrayToDocumentClass downstream, which already goes after an HTTP inbound endpoint. So, perhaps your idea is a bit different and you exactly would like to validate the document already after that .transform(new ByteArrayToDocumentClass()). For that purpose I would suggest to write some simple service activator to be able to call a validator:

        .handle((payload, headers) -> {
                BeanPropertyBindingResult errors = new BeanPropertyBindingResult(payload, "requestPayload");
                    ValidationUtils.invokeValidator(validator, payload, errors);
                    if (errors.hasErrors()) {
                        throw new IllegalStateException(errors.toString());
                    }
                    else {
                        return payload;
                    }
                })