我正在使用spring boot框架,我想通过RabbitMQ将服务中的对象发送到另一个服务:
服务A:
rabbitTemplate.convertAndSend("queue", CreateAccountRequestMessage);
服务B:
@RabbitListener(queues = "queue")
public void onAccountRequested(@Valid CreateAccountRequestMessage createAccountRequestMessage, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG, long tag) throws IOException
{
}
在CreateAccountRequestMessage
类中,我定义了一些验证注释,如@NotEmpty
,@NotNull
等...但是当我从服务A向服务B发送错误消息时,{{1}在调用@Valid
方法
CreateAccountRequestMessage
对象未验证
答案 0 :(得分:3)
您需要在DefaultMessageHandlerMethodFactory
中设置验证器@Autowired
SmartValidator validator;
@Bean
public DefaultMessageHandlerMethodFactory messageHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setValidator(this.validator);
return factory;
}
然后你还需要指定@Payload注释和@Valid注释。
@RabbitListener(queues = "queue")
public void onAccountRequested(@Valid @Payload CreateAccountRequestMessage
createAccountRequestMessage, Channel channel,
@Header(AmqpHeaders.DELIVERY_TAG, long tag) throws IOException
{
}
现在将抛出MethodArgumentNotValidException并丢弃Message,或者您可以将消息发送到死信交换。
答案 1 :(得分:1)
我遇到了同样的问题。除了 SmartValidator,@Praveer 的答案效果很好。我在这里发布了我的解决方案,其灵感来自这篇文章 https://blog.trifork.com/2016/02/29/spring-amqp-payload-validation/
@Configuration
@EnableRabbit
@Slf4j
public class CmsMQConfig implements RabbitListenerConfigurer {
@Value("${dw.rabbitmq.hosts}")
private String hosts;
@Value("${dw.rabbitmq.username}")
private String username;
@Value("${dw.rabbitmq.password}")
private String password;
@Value("${dw.rabbitmq.virtual-host}")
private String virtualHost;
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setMessageConverter(messageConverter());
return factory;
}
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(hosts);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
return connectionFactory;
}
@Bean
public Jackson2JsonMessageConverter messageConverter() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JodaModule());
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return new Jackson2JsonMessageConverter(mapper);
}
@Bean
public DefaultMessageHandlerMethodFactory defaultHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setValidator(amqpValidator());
return factory;
}
@Bean
public Validator amqpValidator() {
return new OptionalValidatorFactoryBean();
}
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setContainerFactory(rabbitListenerContainerFactory());
registrar.setMessageHandlerMethodFactory(defaultHandlerMethodFactory());
}
}