2017-02-28 10 views
4

ここに私のコードスニペットがあります。コンフィギュレーションのためのメッセージJSONメッセージをSpring-rabbitで処理するには?

@RabbitListener(queues = "testMQ") 
public class Receiver { 

    @RabbitHandler 
    public void receive(Message msg){ 
     System.out.println(msg.toString()); 
    } 
} 
  • そして、ここでの受信に対処するための

    @Configuration 
    public class MQConfiguration { 
        @Bean 
        public Receiver receiver() { 
         return new Receiver(); 
        } 
    } 
    
  • ReceiverクラスI RabbitMQの

    に送信されたJSONメッセージです

    • MQConfigurationクラス

      { 
          "id": 1, 
          "name": "My Name", 
          "description": "This is description about me" 
      } 
      

    ただし、アプリケーションを実行したときに次のエラーメッセージが表示されます。

    2017-02-28 17:16:35.931 WARN 11828 --- [cTaskExecutor-1] s.a.r.l.ConditionalRejectingErrorHandler : Execution of Rabbit message listener failed. 
    
    org.springframework.amqp.rabbit.listener.exception.ListenerExecutionFailedException: Listener threw exception 
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.wrapToListenerExecutionFailedExceptionIfNeeded(AbstractMessageListenerContainer.java:872) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:782) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:702) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$001(SimpleMessageListenerContainer.java:95) [spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$1.invokeListener(SimpleMessageListenerContainer.java:186) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.invokeListener(SimpleMessageListenerContainer.java:1227) [spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.executeListener(AbstractMessageListenerContainer.java:683) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.doReceiveAndExecute(SimpleMessageListenerContainer.java:1181) [spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.receiveAndExecute(SimpleMessageListenerContainer.java:1165) [spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer.access$1500(SimpleMessageListenerContainer.java:95) [spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1367) [spring-rabbit-1.7.0.RELEASE.jar:na] 
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60] 
    Caused by: org.springframework.amqp.AmqpException: No method found for class [B 
        at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getHandlerForPayload(DelegatingInvocableHandler.java:127) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler.getMethodNameFor(DelegatingInvocableHandler.java:224) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.adapter.HandlerAdapter.getMethodAsString(HandlerAdapter.java:61) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.invokeHandler(MessagingMessageListenerAdapter.java:140) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.adapter.MessagingMessageListenerAdapter.onMessage(MessagingMessageListenerAdapter.java:106) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:779) ~[spring-rabbit-1.7.0.RELEASE.jar:na] 
        ... 10 common frames omitted 
    

    JSONメッセージをメソッドで印刷したい場合はどうすればよいですか?私は本当に誰もがこれに光を当てることができると感謝しています。あなたは春のブートを使用する場合は

  • 答えて

    0

    、あなただけ設定する必要があります:):

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

    そうでない場合は、設定する必要があります。

    のRabbitMQにJSONを送信するために
    @Bean 
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() { 
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); 
    ... 
        factory.setMessageConverter(new Jackson2JsonMessageConverter()); 
    ... 
        return factory; 
    } 
    

    http://docs.spring.io/spring-amqp/docs/1.7.0.RELEASE/reference/html/_reference.html#async-annotation-driven

    +0

    [spring-rabbit-jsonのサンプル](https://github.com/spring-projects/spring-amqp-samples)も参照してください。 –

    +0

    @Artem Bilanはい、私はSpring Bootを使用していますが、設定クラスで 'jsonMessageConverter()'アノテーションを追加した後でもエラーが表示される場合は、[here](https://github.com/kenshinji/)から自分のコードを確認できます。 rabbitmqtest)。 – kenshinji

    0

    Springブートでそれを消費させるには、content_typeを設定する必要があります。

    PythonプロデューサとJavaコンシューマ(私はPythonからRabbitMQにJSONを送信していましたが、SpringBoot JavaはJSONタスクを受け取ることになっていました)の例を説明しましょう。

    2つの解決策があります。

    解決方法1:JSON文字列として送信し、あなたがCONTENT_TYPE = "text/plainの" に設定し、JSONに変換する必要がありJaksonまたはGSON

    を使用して手動で変換するにはSpring側では、リスナーとして文字列を入力として使用し、手動でオブジェクトを変換します。

    RabbitHandler:

    @RabbitHandler 
    public void receive(String inputString) throws IOException { 
        ObjectMapper objectMapper = new ObjectMapper(); 
        SimStatusReport theResult = objectMapper.readValue(inputString, SimStatusReport.class); 
    
        System.out.println("String instance " + theResult.toString() + 
          " [x] Received"); 
    } 
    

    SimStatusReportオブジェクト:

    import pika 
    import json 
    import uuid 
    
    
    connectionResult = pika.BlockingConnection(pika.ConnectionParameters(host='localhost')) 
    channelResult = connectionResult.channel() 
    routing_key_result = 'sim_results' 
    channelResult.queue_declare(queue=routing_key_result, durable=True) 
    
    def publish_result(sim_status): 
        message =json.dumps(sim_status) 
        channelResult.basic_publish(exchange='', 
               routing_key=routing_key_result, 
               body=message, 
               properties=pika.BasicProperties(
                content_type="text/plain", 
                content_encoding= 'UTF-8', 
                delivery_mode=2, # make message persistent 
             )) 
        print("Sent ", message) 
    
    
    newsim_status = {'id': str(uuid.uuid4()), 't': 0} 
    publish_result(newsim_status) 
    

    解決方法2:ここでは

    import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class SimStatusReport { private String id; private int t; } 

    は私のPythonコードでJSON文字列を送信してみましょうJackson2JsonMessageConverterは、変換を行いますあなたのために自動的に。

    content_type = "application/json"を設定する必要があります。次に、適切なヘッダーをRabbitMQ要求のヘッダーにある__TypeId__に追加する必要があります。あなたは、オブジェクトの正確な名前空間を入れて、ジャクソンがundestand変換するようにする必要があります。ここで

    は、Python(ちょうどpublish_resultののfuction)を使用して、私の例である:

    def publish_result(sim_status): 
        message =json.dumps(sim_status) 
        channelResult.basic_publish(exchange='', 
               routing_key=routing_key_result, 
               body=message, 
               properties=pika.BasicProperties(
                content_type="application/json" 
                headers={'__TypeId__': 'com.zarinbal.simtest.run.model.SimStatusReport'}, 
                content_encoding= 'UTF-8', 
                delivery_mode=2, # make message persistent 
             )) 
        print("Sent ", message) 
    

    次にあなたがJackson2JsonMessageConverterを使用するためにJavaを設定する必要があります。

    ここ
    @Configuration 
        public class RabbitConfiguration { 
         @Bean 
         public MessageConverter jsonMessageConverter() { 
          return new Jackson2JsonMessageConverter(); 
         } 
        } 
    

    は、リスナーのようになります。

    @RabbitListener(queues = "sim_results") 
    public class TaskReceiver { 
        @RabbitHandler 
        public void receive(SimStatusReport in) { 
         System.out.println("Object instance " + in + 
           " [x] Received"); 
        } 
    } 
    

    注: すべてのオブジェクトに、すべてのプロパティとすべての引数コンストラクタのセッターとゲッターがあることを確認してください。私は@Data、@ NoArgsConstructor、および@AllArgsConstructorを使用して自動的に生成します。

    関連する問題