SpringBoot JmsListener:忽略TypeId

问题描述

我目前正在使用SpringBoot JMS,但有些困惑。

当我在网络上使用RestTemplate时,发送方和接收方之间的合同为JSON格式。发送者如何生成JSON(或从哪个类生成)都没有关系。这意味着发送方不必具有与接收方相同的DTO类。

我认为这同样适用于JMS。不幸的是,发送者和接收者必须具有完全相同的类别。我觉得这不切实际。

当然,我可以只在两侧发送一个字符串(包含JSON)。但是我实际上希望Spring能够自己做到这一点。为了使代码保持简单,我只想告诉Spring“在这里将此对象作为JSON发送”。另一方面,“将JSON解析到该对象中”。

当我运行下面的示例时,我收到以下错误消息: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [com.example.demo.MyObject2] to [com.example.demo.MyObject] for org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverteradapter$LazyResolutionMessage@3c60bcf

我只是不了解原理,还是我的思想如此荒谬,以至于这不是“正常”方式,您必须手动做很多事情?

这是我的代码(注意:MyObjectMyObject2都只有一个属性(字符串key):

@SpringBootApplication
@EnableJms
public class DemoApplication implements CommandLineRunner {

    @Autowired
    private jmstemplate jmstemplate;

    public static void main(String[] args) throws IOException {
        SpringApplication.run(DemoApplication.class,args);
    }

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

        return converter;
    }

    @JmsListener(destination = "test")
    public void test(MyObject dto) {
        System.out.println(dto);
    }

    @Override
    public void run(String... args) throws Exception {
        MyObject2 obj = new MyObject2();
        obj.setKey("Test me");

        jmstemplate.convertAndSend("test",obj);
    }
}

解决方法

请参见

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

在转换器上。

在发送方,将MyObject.class中的myObject映射到消费者方,将myObject映射到MyOtherObject.class