I'm writing some message consumer for an AWS SQS and want to validate the received message by using the javax.validation.constraints annotations. Unfortunately I had to find out, that the used PayloadArgumentResolver of the spring-cloud-aws-messaging dependency uses a NoOpValidator. So I tried to inject my own HandlerMethodArgumentResolver for the payload.
@Bean
public QueueMessageHandlerFactory queueMessageHandlerFactory(
final ObjectMapper objectMapper, final Validator hibernateValidator) {
final MappingJackson2MessageConverter jacksonMessageConverter =
new MappingJackson2MessageConverter();
jacksonMessageConverter.setSerializedPayloadClass(String.class);
jacksonMessageConverter.setStrictContentTypeMatch(true);
jacksonMessageConverter.setObjectMapper(objectMapper);
final QueueMessageHandlerFactory factory = new QueueMessageHandlerFactory();
final List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<>();
argumentResolvers.add(new HeaderMethodArgumentResolver(null, null));
argumentResolvers.add(new HeadersMethodArgumentResolver());
argumentResolvers.add(new NotificationSubjectArgumentResolver());
argumentResolvers.add(new AcknowledgmentHandlerMethodArgumentResolver("Acknowledgment"));
argumentResolvers.add(new VisibilityHandlerMethodArgumentResolver("Visibility"));
final PayloadArgumentResolver payloadArgumentResolver =
new PayloadArgumentResolver(jacksonMessageConverter, hibernateValidator);
argumentResolvers.add(payloadArgumentResolver);
factory.setArgumentResolvers(argumentResolvers);
return factory;
}
So far so good and at first sight, it works well... BUT as you can see I had to add the already in QueueMessageHandler existing argument resolvers as well to resolve the headers via @Headers/@Header of the message, too.
@SqsListener(
value = "queue",
deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
public void consume(
@Payload @Validated final QueueMessage queueMessage,
@Headers final Map<String,Object> headers) {
}
When I only add my PayloadArgumentResolver with the hibernate validator, it will be also used to resolve the headers, doh!
Is there any pretty solution for this or should I open an issue at spring-cloud-aws? I just want my payload to be validated via annotations :(