【问题标题】:Spring - Validate incoming message in RabbitMQ listenerSpring - 在 RabbitMQ 侦听器中验证传入消息
【发布时间】:2018-05-03 19:42:52
【问题描述】:

我正在使用 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 发送错误消息时,@Valid 注释不起作用并且@ 987654327@ 对象在调用onAccountRequested 方法之前没有经过验证。

【问题讨论】:

    标签: java spring validation spring-mvc rabbitmq


    【解决方案1】:

    我遇到了同样的问题。 @Praveer 的答案很好,除了 SmartValidator。我在这里发布了我的解决方案,该解决方案的灵感来自这篇文章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());
        }
    }
    

    【讨论】:

      【解决方案2】:

      您需要在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 将被抛出并且消息将被丢弃,或者您可以将消息发送到死信交换。

      【讨论】:

      • 它对我不起作用。 No qualifying bean of type 'org.springframework.validation.SmartValidator' available
      • @Sifeng 您在下面的回答是正确的,使用的验证器可能会因应用设置而异。
      猜你喜欢
      • 2017-11-24
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 2021-04-11
      • 2019-06-17
      • 2020-06-13
      • 2021-03-16
      • 1970-01-01
      相关资源
      最近更新 更多