[英]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.