Spring 与不同包中的模型进行消息传递

Spring messaging with models in different packages

这是我正在尝试做的事情:

应用程序 1(消费者)

com.producer.model.Event - 简单的可序列化模型(id,名称)

应用程序 2(生产者)

com.consumer.integration.model.Event - 简单的序列化模型(id,名称)

序列化配置

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

现在当我生成一条消息时

@Override
public void publishEvent(Event event) {
    log.debug("Publish event Event : {}", event);
    jmsTemplate.convertAndSend(eventTopic, event);
}

消费者

@Override
@JmsListener(destination = "${jmsConfig.eventTopic}", containerFactory = "topicListenerFactory")
public void handleEvent(Event event) {
    log.debug("Received an event {}", event);
}

消费方投诉机型包装不一样

    MessageConversionException: Failed to resolve type id [com.producer.model.Event]
    ...
    Caused by: java.lang.ClassNotFoundException: com.producer.model.Event

因此反序列化在消费者中失败,因为它找不到以 _type 值传递的包。

  1. 为什么我们还需要传递任何包裹相关信息?它泄露了不需要的信息...

  2. 处理这些情况的正确方法是什么。应该是比较常见的情况吧?

编辑:

在 Gary Russell 的帮助下,我解决了这个问题。这就是你想要做的。

使用所需的类型在生产者和消费者中定义映射器:

@Bean
public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    HashMap<String, Class<?>> typeIdMappings = new HashMap<>();
    typeIdMappings.put(Event.class.getSimpleName(), Event.class);
    converter.setTypeIdMappings(typeIdMappings);
    converter.setTypeIdPropertyName("_type");
    return converter;
}

重要的是

这样您就可以使用一个映射器在两个服务之间匹配多个对象。

/**
 * 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) {

在生产者端将源 class 映射到类型 ID,在消费者端将类型 ID 映射到目标 class。

(这就是它被称为 MappingJackson... 的原因)。