We are using Spring Integration to process a JSON payload passed into a RESTful endpoint. As part of this flow we are using a filter to validate the JSON:
.filter(schemaValidationFilter, s -> s
.discardFlow(f -> f
.handle(message -> {
throw new SchemaValidationException(message);
}))
)
This works great. However, if the validation fails we want to capture the parsing error and return that to the user so they can act on the error. Here is the overridden accept method in the SchemaValidationFilter class:
@Override
public boolean accept(Message<?> message) {
Assert.notNull(message);
Assert.isTrue(message.getHeaders().containsKey(TYPE_NAME));
String historyType = (String)message.getHeaders().get(TYPE_NAME);
JSONObject payload = (JSONObject) message.getPayload();
String jsonString = payload.toJSONString();
try {
ProcessingReport report = schemaValidator.validate(historyType, payload);
return report.isSuccess();
} catch (IOException | ProcessingException e) {
throw new MessagingException(message, e);
}
}
What we have done is in the catch block we throw a MessageException which seems to solve the problem. However this seems to break what a filter should do (simply return a true or false).
Is there a best practice for passing the error details from the filter to the client? Is the filter the right solution for this use case?
Thanks for your help! John
I'd say you go correct way. Please, refer to the
XmlValidatingMessageSelector
, so yourJsonValidatingMessageSelector
should be similar and must follow the same design.Since we have a
throwExceptionOnRejection
option we always can be sure that throwing Exception instead of justtrue/false
is correct behavior.What Gary says is good, too, but according to the existing logic in that
MessageSelector
impl we can go ahead with the same and continue to use.filter()
, but, of course, already without.discardFlow()
, because we won't send invalid message to thediscardChannel
.When your
JsonValidatingMessageSelector
is ready, feel free to contribute it back to the Framework!