SpringBoot JmsListener: 忽略 TypeId

huangapple go评论77阅读模式
英文:

SpringBoot JmsListener: Ignore TypeId

问题

以下是您要翻译的内容:

我目前正在使用 SpringBoot JMS 进行工作,有些困惑。

当我在 web 上使用 RestTemplate 时,发送者和接收者之间的契约是 JSON 格式。无论发送者如何生成 JSON(或来自哪个类),这都无关紧要。这意味着发送者不必拥有与接收者相同的 DTO 类。

我以为在 JMS 中也会是同样的情况。不幸的是,发送者和接收者必须要有完全相同的类。我觉得这在某种程度上不太实用。

当然,我可以在两边都只发送一个包含 JSON 的字符串。但我实际上希望 Spring 自己能够做到这一点。为了保持代码简单,我只想告诉 Spring “嘿,把这个对象以 JSON 的形式发送过去”。然后在另一边只需“将该 JSON 解析为这个对象”。

当我运行下面的示例时,我会得到以下错误消息:
org.springframework.messaging.converter.MessageConversionException: 无法从 [com.example.demo.MyObject2] 转换为 [com.example.demo.MyObject],用于 org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage@3c60bcf

我是不是没有理解这个原则,还是我的想法太荒谬,不是“正常”的方式,需要手动完成很多工作?

以下是我的代码(注意:MyObjectMyObject2 都只有一个属性(String 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);
	}
}
英文:

I am currently working with SpringBoot JMS and I am a bit confused.

When I use the RestTemplate on the web the contract between sender and receiver is the JSON format. It doesn't matter how the sender generates the JSON (or from which class). That means the sender does not have to have the same DTO class as the receiver.

I assumed that the same would apply to JMS. Unfortunately, the sender and the receiver must have exactly the same class. I find that somehow impractical.

Of course I could just send a string (containing a JSON) on both sides. But I actually expect Spring to do this by itself. To keep the code simple I just want to tell Spring "here send this object as JSON". And on the other side just "parse that JSON into this object".

When I run the example below I get the following error message:
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

Did I just not understand the principle or is my thought so absurd that it is not the "normal" way and you have to do a lot by hand?

Here is my code (Note: MyObject and MyObject2 have both just one attribute (String 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);
	}
}

答案1

得分: 0

	/**
	 * 如果需要,指定从类型 ID 到 Java 类的映射。
	 * 这允许在类型 ID 消息属性中使用合成的 ID,而不是传输 Java 类名。
	 * <p>默认情况下没有自定义映射,即传输原始的 Java 类名。
	 * @param typeIdMappings 具有类型 ID 值作为键和 Java 类作为值的映射
	 */
	public void setTypeIdMappings(Map<String, Class<?>> typeIdMappings) {

在转换器上。

在发送方,将 MyObject.classmyObject 进行映射,而在消费方,将 myObject 映射到 MyOtherObject.class

英文:

See

	/**
	 * 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.
	 * &lt;p&gt;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&lt;String, Class&lt;?&gt;&gt; typeIdMappings) {

on the converter.

On sending side, map MyObject.class from myObject and on the consumer side, map myObject to MyOtherObject.class.

huangapple
  • 本文由 发表于 2020年9月11日 20:16:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/63846933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定