簡體   English   中英

Spring - 在 RabbitMQ 偵聽器中驗證傳入消息

[英]Spring - Validate incoming message in RabbitMQ listener

我正在使用 Spring Boot 框架。 我想通過 RabbitMQ 將一個對象從一個服務發送到另一個服務,如下所示:

服務一:

rabbitTemplate.convertAndSend("queue", createAccountRequestMessage);

服務乙:

@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注釋不起作用並且CreateAccountRequestMessage對象在調用onAccountRequested方法之前未驗證.

您需要在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並丟棄消息,或者您可以將消息發送到死信交換。

我有同樣的問題。 除了 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());
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM