Spring boot JMS parsing json метод обработки объекта - PullRequest
0 голосов
/ 07 мая 2020

У меня есть приложение 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)
            }
        }

Как я могу решить эту проблему с помощью аргумента метода или какой-либо аннотации?

...