简体   繁体   English

将 Json 对象序列化为 Spring 的 Rabbit Listener 中的 Java 对象会引发异常

[英]Json object serialization to Java object inside Spring's Rabbit Listener throws exception

I want to listen for messages coming into Rabbit queue with Spring's rabbit listener.我想用 Spring 的 rabbit 侦听器侦听进入 Rabbit 队列的消息。 My class looks very basic like this:我的课程看起来非常基本,如下所示:

    @Component
public class MailMessageRabbitListener {
    private MailRepository mailRepository;
    private MailService mailService;

    @Autowired
    public MailMessageRabbitListener(MailRepository mailRepository, MailService mailService) {
        this.mailRepository = mailRepository;
        this.mailService = mailService;
    }

    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @RabbitListener(queues = "msmail.queue")
    public void receiveMailMessage(JsonMailMessage jsonMailMessage) throws Exception {
        System.out.println(jsonMailMessage);
    }
}

My mapping class JsonMailMessage looks like this:我的映射类 JsonMailMessage 如下所示:

@Data
@NoArgsConstructor
@RequiredArgsConstructor
public class JsonMailMessage {
    @NonNull
    private String userToken;
    @NonNull
    private String sendTo;
    @NonNull
    private String subject;
    @NonNull
    private String content;
    @NonNull
    private String[] files;

}

Now I'm able to successfully listen to a queue, the problem is when I send message such as this within Rabbit queue:现在我能够成功收听队列,问题是当我在 Rabbit 队列中发送这样的消息时:

兔子消息

Json array is filled with base64 encoded files, which should be basic String expressions, so the Jackson2JsonMessageConverter should be able to convert the files. Json 数组填充了 base64 编码的文件,这些文件应该是基本的 String 表达式,因此 Jackson2JsonMessageConverter 应该能够转换文件。

I'm however getting this kind of exception:但是,我遇到了这种异常:

Bean [---------messaging.MailMessageRabbitListener@35ff072c]
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:185) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:120) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:1414) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.actualInvokeListener(AbstractMessageListenerContainer.java:1337) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:1324) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:1303) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:785) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:769) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$700(SimpleMessageListenerContainer.java:77) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1010) [spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_171]
Caused by: org.springframework.messaging.converter.MessageConversionException: Cannot convert from [[B] to [-----dto.JsonMailMessage] for GenericMessage [payload=byte[118], headers={amqp_receivedDeliveryMode=NON_PERSISTENT, amqp_receivedRoutingKey=msmail.queue, amqp_deliveryTag=1, amqp_consumerQueue=msmail.queue, amqp_redelivered=false, id=b997e8cb-3424-df90-5370-aa4cf79175be, amqp_consumerTag=amq.ctag-lL9Y6R67fJc6DyCHAiWQRA, Content-Type=application/json, timestamp=1538554985476}]
    at org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver.resolveArgument(PayloadArgumentResolver.java:144) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:116) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:137) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.messaging.handler.invocation.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:109) ~[spring-messaging-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.invoke(HandlerAdapter.java:51) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:182) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    ... 10 common frames omitted

Update更新

It's working, the message is getting converted to Java object.它正在工作,消息正在转换为 Java 对象。 The problem starts when I want to return the object directly from Listener method.当我想直接从 Listener 方法返回对象时,问题就开始了。

 @RabbitListener(queues = "msmail.queue")
public JsonMailMessage receiveMailMessage(JsonMailMessage jsonMailMessage){
  return jsonMailMessage;
}

It throws different exception:它抛出不同的异常:

Caused by: org.springframework.amqp.AmqpException: Cannot determine ReplyTo message property value: Request message does not contain reply-to property, and no default response Exchange was set.
    at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.getReplyToAddress(AbstractAdaptableMessageListener.java:398) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    at org.springframework.amqp.rabbit.listener.adapter.AbstractAdaptableMessageListener.handleResult(AbstractAdaptableMessageListener.java:307) ~[spring-rabbit-2.0.3.RELEASE.jar:2.0.3.RELEASE]
    ... 10 common frames omitte

The content_type is a well-known property not and arbitrary header; content_type是众所周知的属性,不是任意标头; add it to Properties: instead. 将其添加到“ Properties:

Click the ? 点击? in the UI to see the well-known properties. 在用户界面中查看知名属性。

Since there is no content type, the converter simply returns the byte[] unchanged. 由于没有内容类型,因此转换器只返回未更改的byte[]

Remove the MessageConverter Bean and try.删除MessageConverter Bean 并尝试。

I also faced the same problem, after removing MessageConverter Bean, it works fine.我也遇到了同样的问题,删除MessageConverter Bean 后,它工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM