У меня есть приложение Spring Boot, которое обрабатывает входящие ArtemisMQ
@JmsListener(destination = "work-started")
public fun workStarted(work: Work) {
handleNewWork(work)
}
Я создал MappingJackson2MessageConverter
с настройкой по умолчанию
@Bean
fun jacksonJmsMessageConverter(): MessageConverter? {
val converter = MappingJackson2MessageConverter()
converter.setTargetType(MessageType.OBJECT)
// I don't receive class type
converter.setTypeIdPropertyName("_type")
return converter
}
И application.properties
spring.artemis.mode=native
spring.artemis.host=localhost
spring.artemis.port=61616
spring.artemis.user=root
spring.artemis.password=root
Я хочу, чтобы Spring анализировал сообщение входным объектом, в моем случае у меня есть Work
в качестве аргумента, который, как я ожидаю, будет проанализирован из json.
Когда я запускаю его, я получаю эта ошибка:
Caused by: org.springframework.jms.support.converter.MessageConversionException: Could not find type id property [_type] on message [null] from destination [ActiveMQQueue[work-started]]
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.getJavaTypeForMessage(MappingJackson2MessageConverter.java:456) ~[spring-jms-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.jms.support.converter.MappingJackson2MessageConverter.fromMessage(MappingJackson2MessageConverter.java:232) ~[spring-jms-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener.extractMessage(AbstractAdaptableMessageListener.java:251) ~[spring-jms-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter.extractPayload(AbstractAdaptableMessageListener.java:476) ~[spring-jms-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage.unwrapPayload(AbstractAdaptableMessageListener.java:543) ~[spring-jms-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.jms.listener.adapter.AbstractAdaptableMessageListener$MessagingMessageConverterAdapter$LazyResolutionMessage.getPayload(AbstractAdaptableMessageListener.java:525) ~[spring-jms-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.messaging.handler.annotation.support.PayloadMethodArgumentResolver.resolveArgument(PayloadMethodArgumentResolver.java:116) ~[spring-messaging-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:117) ~[spring-messaging-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:148) ~[spring-messaging-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:116) ~[spring-messaging-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:114) ~[spring-jms-5.2.5.RELEASE.jar:5.2.5.RELEASE]
... 10 common frames omitted
Он ищет _type
свойство, которое отсутствует.
Я сделал небольшой взлом, чтобы проверить, верна ли моя идея. Здесь я сопоставляю имя пункта назначения с классом, чтобы он позже проанализировал. Но это кажется совершенно неправильным способом сделать это.
val converter = object : MappingJackson2MessageConverter() {
override fun getJavaTypeForMessage(message: Message): JavaType {
var clazz :Class<*>? = null
val jmsDestination = message.jmsDestination as ActiveMQQueue
when(jmsDestination.address) {
"work-started" -> {
clazz = Work::class.java
}
}
if(clazz == null) {
return super.getJavaTypeForMessage(message)
}
return jacksonObjectMapper().typeFactory.constructType(clazz)
}
}
Как я могу решить эту проблему с помощью аргумента метода или какой-либо аннотации?