Chr*_*ein 4 java spring rabbitmq spring-boot
我们正在构建一个通过 RabbitMQ 接收消息的 Spring Boot 应用程序 (2.0.4-RELEASE)。因此application.properties包含与兔子相关的配置:
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
Run Code Online (Sandbox Code Playgroud)
配置:
@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("");
}
Run Code Online (Sandbox Code Playgroud)
消息消费者:
@RabbitListener(queues = "myFancyQueue")
public void receive(Object message) {
...
}
Run Code Online (Sandbox Code Playgroud)
当接收到特定类型的消息(例如__TypeId__: my.fancy.package.Clazz)时,会抛出以下错误:
引起原因:java.lang.IllegalArgumentException:类“my.fancy.package.Clazz”不在受信任的包中:[java.util,java.lang]。如果您认为反序列化此类是安全的,请提供其名称。如果序列化仅由可信来源完成,您还可以启用全部信任 (*)。
据我所知,到目前为止,activeMQ 通过application.propertiesas提供了一个配置选项
spring.activemq.packages.trust-all=
Run Code Online (Sandbox Code Playgroud)
或者
spring.activemq.packages.trusted=
Run Code Online (Sandbox Code Playgroud)
但我找不到任何适用于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;
}
Run Code Online (Sandbox Code Playgroud)
并将消息消费者更改为
@Resource(name = "jsonMessageConverter")
private MessageConverter messageConverter;
@RabbitListener(queues = "${uploaded.files.queue}")
public void receive(Message message) {
FileUploadMessage uploadMessage = (FileUploadMessage) messageConverter.fromMessage(message);
...
}
Run Code Online (Sandbox Code Playgroud)
另外添加一个类映射器,允许导入未知类型并设置导入时消息应转换为的默认类型:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
关于如何改进这个解决方案有什么建议吗?
我通过在正在使用的 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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2940 次 |
| 最近记录: |