簡體   English   中英

用於RabbitMQ的Spring Boot可信軟件包

[英]Spring Boot trusted packages for rabbitmq

我們正在構建一個Spring Boot應用程序(2.0.4-RELEASE),該應用程序通過RabbitMQ接收消息。 因此, application.properties包含與Rabbit相關的配置:

spring.rabbitmq.addresses=****
spring.rabbitmq.username=****
spring.rabbitmq.password=****
spring.rabbitmq.listener.simple.concurrency=2
spring.rabbitmq.listener.simple.prefetch=5
spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.max-attempts=5

組態:

@Bean
public TopicExchange fileUpdate() {
    return new TopicExchange("my.fancy.exchange", true, false);
}

@Bean
public Queue fileUpload() {
    return new Queue("myFancyQueue", true);
}

@Bean
public Binding bindingUpload(Queue queue, TopicExchange eventExchange) {
    return BindingBuilder.bind(queue).to(eventExchange).with("");
}

消息使用者:

@RabbitListener(queues = "myFancyQueue")
public void receive(Object message) {
    ...
}

收到特定類型的消息(例如__TypeId__: my.fancy.package.Clazz )時,將引發以下錯誤:

原因:java.lang.IllegalArgumentException:類'my.fancy.package.Clazz'不在受信任的程序包中:[java.util,java.lang]。 如果您認為該類別可以安全地反序列化,請提供其名稱。 如果序列化僅由受信任的源完成,則還可以啟用全部信任(*)。

到目前為止,我發現activeMQ通過application.properties為它提供了一個配置選項,如下所示:

spring.activemq.packages.trust-all=

要么

spring.activemq.packages.trusted=

但我找不到適用於RabbitMQ的任何類似選項。 到目前為止,我一直在使用一種解決方法來解決我的問題,但是在配置文件中當然也可以有這樣的選項。

到目前為止,我的解決方案:

添加到配置類:

@Bean
public MessageConverter jsonMessageConverter() {
    Jackson2JsonMessageConverter jsonMessageConverter = new Jackson2JsonMessageConverter(new ObjectMapper());
    jsonMessageConverter.setClassMapper(new ImporterClassMapper(FileUploadMessage.class));        
    return jsonMessageConverter;
}

@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
    RabbitTemplate template = new RabbitTemplate(connectionFactory);
    template.setMessageConverter(jsonMessageConverter());
    return template;
}

並將消息使用者更改為

@Resource(name = "jsonMessageConverter")
private MessageConverter messageConverter;

@RabbitListener(queues = "${uploaded.files.queue}")
public void receive(Message message) {
    FileUploadMessage uploadMessage = (FileUploadMessage) messageConverter.fromMessage(message);
    ...
}

加上添加一個類映射器,該類映射器允許導入未知類型,並設置導入時將消息強制轉換為的默認類型:

public class ImporterClassMapper implements ClassMapper, InitializingBean {

    private volatile Class<?> defaultType;

    public ImporterClassMapper(Class<?> defaultType) {
        this.defaultType = defaultType;
    }    

    @Override
    public void afterPropertiesSet() throws Exception {
        // nothing to do
    }

    @Override
    public void fromClass(Class<?> clazz, MessageProperties properties) {
        // avoid setting __TypeId__ header so consumers from other modules can implement their own DTOs
    }

    @Override
    public Class<?> toClass(MessageProperties properties) {
        return this.defaultType;
    }

    public void setClass(Class<?> type) {
        this.defaultType = type;
    }
}

對如何改進此解決方案有何建議?

我通過在使用的Spring AMQP ClassMapper上設置受信任的軟件包來修復了相同的錯誤。

@Configuration
public class RabbitConfig {

    @Bean
    @Scope("prototype")
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(SimpleRabbitListenerContainerFactory factory, ObjectMapper objectMapper) {
        factory.setMessageConverter(jsonToMapMessageConverter(objectMapper));
        return factory;
    }

    @Bean
    public MessageConverter jsonToMapMessageConverter(ObjectMapper objectMapper) {
        Jackson2JsonMessageConverter messageConverter = new ImplicitJsonMessageConverter(objectMapper);
        DefaultClassMapper classMapper = new DefaultClassMapper();
        classMapper.setTrustedPackages("*");
        classMapper.setDefaultType(Map.class);
        messageConverter.setClassMapper(classMapper);
        return messageConverter;
    }

    public static class ImplicitJsonMessageConverter extends Jackson2JsonMessageConverter {    
        public ImplicitJsonMessageConverter(ObjectMapper jsonObjectMapper) {
            super(jsonObjectMapper, "*");
        }    
        @Override
        public Object fromMessage(Message message) throws MessageConversionException {
            message.getMessageProperties().setContentType("application/json");
            return super.fromMessage(message);
        }
    }
}

暫無
暫無

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

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