"Body not assignable to class" 使用 ActiveMQ Artemis & Spring 启动

"Body not assignable to class" using ActiveMQ Artemis & Spring Boot

我开始使用 Artemis 和 JMS,但我无法收到消息。 生产者正确询问消息;这是得到并正确回复。问题在最后阶段,获取数据。

我尝试指定类型,但没有成功:

resp.setJMSType("com.nesdl.flyaway.core.modelmessages.ApplicationsEvent");
log.debug(resp.getJMSType() + " / " + resp.getBody(String.class));
ApplicationsEvent response = resp.getBody(ApplicationsEvent.class);

我得到这个堆栈跟踪:

2021-06-02 09:39:40.060 DEBUG 14288 --- [p-nio-80-exec-1] c.n.f.f.s.ApplicationsServicesImpl       : com.nesdl.flyaway.core.modelmessages.ApplicationsEvent / is null : "{\"applicationsDto\":[{\"id\":1,\"version\":0,\"dateCreated\":\"2021-05-18T17:52:30+0000\",\"dateLastModified\":\"2021-05-18T17:52:30+0000\",\"uuid\":\"66ef5e19-e5ac-48d1-86c8-85d26e0fa205\",\"valid\":true,\"modified\":false,\"toHistorize\":false,\"name\":\"TestApp\",\"description\":\"Première application\"}]}"
2021-06-02 09:39:40.066 DEBUG 14288 --- [p-nio-80-exec-1] o.s.web.servlet.DispatcherServlet        : Failed to complete request: javax.jms.MessageFormatException: Body not assignable to class com.nesdl.flyaway.core.modelmessages.ApplicationsEvent
2021-06-02 09:39:40.071 ERROR 14288 --- [p-nio-80-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.jms.MessageFormatException: Body not assignable to class com.nesdl.flyaway.core.modelmessages.ApplicationsEvent] with root cause

javax.jms.MessageFormatException: Body not assignable to class com.nesdl.flyaway.core.modelmessages.ApplicationsEvent
    at org.apache.activemq.artemis.jms.client.ActiveMQMessage.getBody(ActiveMQMessage.java:740) ~[artemis-jms-client-2.15.0.jar:2.15.0]
    at com.nesdl.flyaway.front.services.ApplicationsServicesImpl.getApplications(ApplicationsServicesImpl.java:52) ~[classes/:na]
    at com.nesdl.flyaway.front.services.ApplicationsServicesImpl$$FastClassBySpringCGLIB$3cab08.invoke(<generated>) ~[classes/:na]
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.6.jar:5.3.6]
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.6.jar:5.3.6]

等等

因此,消息返回的内容是好的数据,但无法分配给特定的class。

我的制作人

@Override
public List<ApplicationDto> getApplications() throws IOException, JMSException {
    ApplicationsEvent mess = ApplicationsEvent.builder()
            .applicationsDto(new ArrayList<>())
            .build();
    log.debug("message sent :"+mess.toString());
    Message resp = jmsTemplate.sendAndReceive(JmsSystemConfig.APPLICATIONS_QUEUE, new MessageCreator() {
        @SneakyThrows
        @Override
        public Message createMessage(Session session) throws JMSException {
            Message appMess = session.createTextMessage(objectMapper.writeValueAsString(mess));
            appMess.setStringProperty("_type","com.nesdl.flyaway.core.modelmessages.ApplicationsEvent");
            return appMess;
        }
    });
    resp.setJMSType("com.nesdl.flyaway.core.modelmessages.ApplicationsEvent");
    log.debug(resp.getJMSType() + " / " + resp.getBody(String.class));
    ApplicationsEvent response = resp.getBody(ApplicationsEvent.class);
    log.debug(response.getApplicationsDto().toString());
    return response.getApplicationsDto();
}

我的消费者

@JmsListener(destination = JmsSystemConfig.APPLICATIONS_QUEUE)
public void replyApplications(@Payload ApplicationsEvent appsEvent, @Headers MessageHeaders headers, Message message) throws JMSException, JsonProcessingException {
    ApplicationsEvent resp = ApplicationsEvent.builder()
            .applicationsDto(as.getApplications())
            .build();
    jmsTemplate.convertAndSend(message.getJMSReplyTo(),objectMapper.writeValueAsString(resp));
    log.debug("reply ok "+resp.toString()+" / "+objectMapper.writeValueAsString(resp));
}

和 JMS 配置

@Configuration
public class JmsConfig {

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

它说您正在尝试将 JMS 消息正文分配或添加到“事件 class”。 事件通常有一个命名的重写方法,用于在事件被触发时将代码放入 运行 该代码。

这里可能是这个,编译器错误信息好像是“resp”,一个消息体和“response”ApplicationsEvent。

resp.setJMSType("com.nesdl.flyaway.core.modelmessages.ApplicationsEvent");
        log.debug(resp.getJMSType() + " / " + resp.getBody(String.class));
        ApplicationsEvent response = resp.getBody(ApplicationsEvent.class);
        log.debug(response.getApplicationsDto().toString());

这里的根本问题是您正在发送 text 消息,但您试图使用 [=15] 将其直接分配给 com.nesdl.flyaway.core.modelmessages.ApplicationsEvent 对象=] 这是行不通的。您必须将文本转换为该对象,就像使用 objectMapper.writeValueAsString 将此对象转换为文本一样,例如:

ApplicationsEvent response = objectMapper.readValue(resp.getBody(String.class), ApplicationsEvent.class);

此外,没有理由在这里调用 javax.jms.Message.setJMSType()。它基本上什么都不做,所以你可以安全地删除它。