Spring使用MappingJackson2MessageConverter發送接收ActiveMQ訊息

來源:互聯網
上載者:User

標籤:gety   設定   obj   封裝   str   factory   ext   ppi   讀取   

一、Spring使用JmsTemplate簡化對JMS的訪問

在JAVA對JMS隊列訪問中,使用預設的JMS支援將存在大量的檢查型異常。通過Spring的支援,可以將所有的JMS的檢查型異常轉換為運行時非檢查異常。以及在Spring中,通過配置JMSConnectionFactory的DefaultDestinationName指定發送和接收目的地。

下面是ActiveMQ的串連factory配置:

1     @Bean2     public ActiveMQConnectionFactory getAMQFactory() {3         ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory();4         mqConnectionFactory.setBrokerURL("tcp://59.110.231.87:61616");5         mqConnectionFactory.setTrustedPackages(Arrays.asList("com.edoctor.bean"));6         return mqConnectionFactory;7     }

下面是JmsTemplate的配置:

1     @Bean2     public JmsTemplate getJmsTemplate(ActiveMQConnectionFactory cf, MessageConverter messageConverter) {3         JmsTemplate jmsTemplate = new JmsTemplate(cf);4         jmsTemplate.setDefaultDestinationName("com.demo.testActiveMQ");5         jmsTemplate.setMessageConverter(messageConverter);6         // pubSubDomain = true 為隊列模式,false為訂閱發布模式7         jmsTemplate.setPubSubDomain(false);8         return jmsTemplate;9     }

我是使用純JAVA註解配置的Bean,基於xml的也類似,可以自行搜尋。

上述欄位含義如下:

setDefaultDestinationName:設定ActiveMQ的隊列名稱,當然如果下面的pubSubDomain為true,則為主題名稱

setMessageConverter:設定ActiveMQ的訊息轉換器,預設不寫的話是使用的Spring的SimpleMessageConverter

setPubSubDomain:值true代表該Template為隊列,false為主題

 

2.Spring的訊息轉換器的種類

Spring內建的訊息轉換器可以大大簡化訊息的讀取以及寫入,所有的訊息轉換器都位於org.springframework.jms.support.converter包中。

訊息轉換器 功能
MappingJacksonMessageConverter

使用Jackson JSON庫實現訊息與JSON格式之間的相互轉換

MappingJackson2MessageConverter

使用Jackson 2 JSON庫實現訊息與JSON格式之間相互轉換

MarshallingMessageConverter

使用JAXB庫實現訊息與XML格式之間的相互轉換

SimpleMessageConverter

實現String與TextMessage之間的相互轉換,位元組數組與Bytes
Message之間的相互轉換,Map與MapMessage之間的相互轉換
以及Serializable對象與ObjectMessage之間的相互轉換

預設情況下,JmsTemplate在convertAndSend()方法中會使用SimpleMessage Converter。但是通過將訊息轉換器聲明為bean並將其注入到JmsTemplate的messageConverter屬性中,我們可以重寫這種行為。例如,如果你想使用JSON訊息的話,那麼可以聲明一個MappingJackson2MessageConverter bean。

 

三、配置MappingJackson2MessageConverter的Bean

上文的JmsTemplate已經成功注入了ActiveMQConnectionFactory,下面就將注入我們的MessageConverter。

由於使用預設的SimpleMessageConverter如果是Object對象的話,必須將對象序列化,如果對象包含封裝類例如Integer將無法實現序列化,因此,我打算使用基於json的MappingJackson2MessageConverter序列化對象發送以及接受,該配置會實現自動序列化。但是在網上查閱相關文檔,發現幾乎沒有中文介紹配置MappingJackson2MessageConverter的,因此,希望寫下這個配置協助大家。

MappingJackson2MessageConverter在JavaDoc中的詳細配置:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/jms/support/converter/MappingJackson2MessageConverter.html

對於文檔和介紹,上述連結有詳細說明,裡面主要提到一點:

意思是,如果需要在接受Object對象格式的訊息的時候,需要配置這項屬性,以及這項屬性需要參考typeIdMappings。

我們再看一下這個Map的說明:

這個Map以String為key,Class為值,而這裡的Key就是對應的typeId,Value就是你需要序列化的類。所以只需要構建這樣一個Map就可以允許從MQ中接受類對象型的訊息了。下面是我的POJO(注意該在MQ中發送接收的對象務必有無參建構函式)

 1 public class TestJMS { 2     private String name; 3     private Integer age; 4     private String email; 5  6     public TestJMS() { 7     } 8  9     public TestJMS(String name, Integer age, String email) {10         this.name = name;11         this.age = age;12         this.email = email;13     }14 15     public String getName() {16         return name;17     }18 19     public void setName(String name) {20         this.name = name;21     }22 23     public Integer getAge() {24         return age;25     }26 27     public void setAge(Integer age) {28         this.age = age;29     }30 31     public String getEmail() {32         return email;33     }34 35     public void setEmail(String email) {36         this.email = email;37     }38 39     @Override40     public String toString() {41         return "TestJMS{" +42                 "name=‘" + name + ‘\‘‘ +43                 ", age=" + age +44                 ", email=‘" + email + ‘\‘‘ +45                 ‘}‘;46     }47 }

以及這是注入到JmsTemplate的MappingJackson2MessageConverter的Bean定義

 1     @Bean 2     public MappingJackson2MessageConverter getJacksonMessageConverter() { 3         MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); 4         converter.setTargetType(MessageType.TEXT); 5         // 定義了typeId到Class的Map 6         Map<String, Class<?>> typeIdMap = new HashMap<>(); 7         typeIdMap.put("TestJMS", TestJMS.class); 8         converter.setTypeIdMappings(typeIdMap); 9         // 設定發送到隊列中的typeId的名稱10         converter.setTypeIdPropertyName("TestJMS");11         converter.setEncoding("UTF-8");12         return converter;13     }

通過這樣的注入,實現了Class Object格式無須序列化的對象發送與接受

完整的ActiveMQ基於JAVA註解的配置代碼如下:

 1 import com.test.bean.TestJMS; 2 import org.apache.activemq.ActiveMQConnectionFactory; 3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.jms.core.JmsTemplate; 6 import org.springframework.jms.support.converter.MappingJackson2MessageConverter; 7 import org.springframework.jms.support.converter.MessageConverter; 8 import org.springframework.jms.support.converter.MessageType; 9 10 import java.util.Arrays;11 import java.util.HashMap;12 import java.util.Map;13 14 @Configuration15 public class MQConfig {16 17     @Bean18     public ActiveMQConnectionFactory getAMQFactory() {19         ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory();20         mqConnectionFactory.setBrokerURL("tcp://59.110.231.87:61616");21         mqConnectionFactory.setTrustedPackages(Arrays.asList("com.edoctor.bean"));22         return mqConnectionFactory;23     }24 25     @Bean26     public JmsTemplate getJmsTemplate(ActiveMQConnectionFactory cf, MessageConverter messageConverter) {27         JmsTemplate jmsTemplate = new JmsTemplate(cf);28         jmsTemplate.setDefaultDestinationName("EDoctor.JMSTemplate.queue2");29         jmsTemplate.setMessageConverter(messageConverter);30         // pubSubDomain = true 為隊列模式,false為訂閱發布模式31         jmsTemplate.setPubSubDomain(false);32         return jmsTemplate;33     }34 35     @Bean36     public MappingJackson2MessageConverter getJacksonMessageConverter() {37         MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();38         converter.setTargetType(MessageType.TEXT);39         Map<String, Class<?>> typeIdMap = new HashMap<>();40         typeIdMap.put("TestJMS", TestJMS.class);41         converter.setTypeIdMappings(typeIdMap);42         converter.setTypeIdPropertyName("TestJMS");43         converter.setEncoding("UTF-8");44         return converter;45     }46 47 }
  四、總結
MappingJackson2MessageConverter可以很有效實現MQ的發送和接受序列化,不需要將POJO手動序列化,實現Serializable介面。基於JSON的解析也順應主流技術。因為踩了較多的坑,所以特地留此篇部落格,如果不對的地方,還希望多多指出。
有疑問歡迎留言,謝謝!

Spring使用MappingJackson2MessageConverter發送接收ActiveMQ訊息

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.