【问题标题】:Message conversion after retrieving it from activemq topic从activemq主题中检索后的消息转换
【发布时间】:2018-08-29 14:31:01
【问题描述】:

我想使用 ActiveMQ 作为代理来实现微服务之间的消息传递,但是在将所有设置都设置为应有之后,有一件事让我卡住了。在我描述问题之前,我正在处理消息传递:

生产者配置:

@Slf4j
@Configuration
@EnableJms
public class JmsConfig {

  public static final String EBAY_TOPIC = "ebay.topic";

  @Bean
  public ActiveMQTopic destinationTopic() {

    return new ActiveMQTopic(EBAY_TOPIC);
  }

  @Bean
  public JmsListenerContainerFactory<?> connectionFactory(ConnectionFactory connectionFactory,
                                                          DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    configurer.configure(factory, connectionFactory);
    factory.setPubSubDomain(true);
    return factory;
  }

  @Bean
  public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
  }

  @Bean
  public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
    jmsTemplate.setDefaultDestinationName(EBAY_TOPIC);
    jmsTemplate.setConnectionFactory(connectionFactory);
    jmsTemplate.setMessageConverter(messageConverter);
    jmsTemplate.setPubSubDomain(true);
    return jmsTemplate;
  }
}

生产者发送消息:

@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping("/message")
public class IntercommunicationController {

  private final JmsTemplate jmsTemplate;

  @PostMapping("/send")
  public void sendMessageToOtherService(@RequestBody Message message) {
    jmsTemplate.convertAndSend(JmsConfig.EBAY_TOPIC, message);
  }
}

接收器配置:

@Configuration
@EnableJms
public class JmsConfig {

  public static final String EBAY_TOPIC = "ebay.topic";

  @Bean
  public JmsListenerContainerFactory<?> connectionFactory(ConnectionFactory connectionFactory,
                                                          DefaultJmsListenerContainerFactoryConfigurer configurer,
                                                          ErrorHandler errorHandler) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    configurer.configure(factory, connectionFactory);
    factory.setErrorHandler(errorHandler);
    factory.setPubSubDomain(true);
    return factory;
  }

  @Bean
  public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("_type");
    return converter;
  }
}

接收器实现:

@Slf4j
@Component
public class MessageListener {

  @JmsListener(destination = JmsConfig.EBAY_TOPIC, containerFactory = "connectionFactory")
  public void receiveMessage(@Payload Message receivedMessage) {
    log.info("Got message saying {}", receivedMessage);
  }
}

正在发送的POJO:

@NoArgsConstructor
@Data
public class Message {
  String content;
  String from;
}

问题:

一旦我尝试通过 json 发布对象并将其发送到主题上,我就会收到错误消息。一旦消息到达主题,消费者就无法处理消息的反序列化,因为 TypeIdPropertyName 是我发送给我尝试接收的对象的不同包路径,它们在两个应用程序中都是 1:1 ,但我得到:

2018-03-20 16:32:08.601 ERROR 1568 --- [enerContainer-1] c.g.g.s.c.config.MessageErrorHandler     : Listener method 'public void com.gft.graduate2018.sabb.client.listener.MessageListener.receiveMessage(client.domain.Message)' threw exception; nested exception is org.springframework.jms.support.converter.MessageConversionException: Failed to resolve type id [backend.model.dtos.Message]; nested exception is java.lang.ClassNotFoundException: backend.model.dtos.Message

解决这个问题的正确方法是什么?我最终可能会编写从字符串到对象的自定义解析器,但这可能不是最好的解决方案。希望有人以前处理过它并可以帮助解决这个问题:)

【问题讨论】:

    标签: jms activemq converter messaging spring-messaging


    【解决方案1】:

    看...

    /**
     * Specify mappings from type ids to Java classes, if desired.
     * This allows for synthetic ids in the type id message property,
     * instead of transferring Java class names.
     * <p>Default is no custom mappings, i.e. transferring raw Java class names.
     * @param typeIdMappings a Map with type id values as keys and Java classes as values
     */
    public void setTypeIdMappings(Map<String, Class<?>> typeIdMappings) {
         ...
    }
    

    ...在转换器上。

    设置双方的映射,因此__type 标头只包含一个标记,该标记从发送端的类名映射到接收端的类名。

    【讨论】:

      猜你喜欢
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-06
      • 1970-01-01
      • 2014-04-20
      • 2013-11-24
      • 2012-01-03
      相关资源
      最近更新 更多