欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Spring整合JMS(三)——MessageConverter介紹

系統(tǒng) 1638 0

1.4 ???? 消息轉(zhuǎn)換器 MessageConverter

MessageConverter 的作用主要有兩方面,一方面它可以把我們的非標準化 Message 對象轉(zhuǎn)換成我們的目標 Message 對象,這主要是用在發(fā)送消息的時候;另一方面它又可以把我們的 Message 對象轉(zhuǎn)換成對應(yīng)的目標對象,這主要是用在接收消息的時候。

下面我們就拿發(fā)送一個對象消息來舉例,假設(shè)我們有這樣一個需求:我們平臺有一個發(fā)送郵件的功能,進行發(fā)送的時候我們只是把我們的相關(guān)信息封裝成一個 JMS 消息,然后利用 JMS 進行發(fā)送,在對應(yīng)的消息監(jiān)聽器進行接收到的消息處理時才真正的進行消息發(fā)送。

假設(shè)我們有這么一個 Email 對象:

?

      public class Email implements Serializable {
 
    private static final long serialVersionUID = -658250125732806493L;
 
    private String receiver;
    private String title;
    private String content;
 
    public Email(String receiver, String title, String content) {
        this.receiver = receiver;
        this.title = title;
        this.content = content;
    }
 
    public String getReceiver() {
        return receiver;
    }
 
    public void setReceiver(String receiver) {
        this.receiver = receiver;
    }
 
    public String getTitle() {
        return title;
    }
 
    public void setTitle(String title) {
        this.title = title;
    }
 
    public String getContent() {
        return content;
    }
 
    public void setContent(String content) {
        this.content = content;
    }
 
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Email [receiver=").append(receiver).append(", title=")
                .append(title).append(", content=").append(content).append("]");
        return builder.toString();
    }
    
}
    

?????? 這個 Email 對象包含了一個簡單的接收者 email 地址、郵件主題和郵件內(nèi)容。我們在發(fā)送的時候就把這個對象封裝成一個 ObjectMessage 進行發(fā)送。代碼如下所示:

      public class ProducerServiceImpl implements ProducerService {
 
    @Autowired
    private JmsTemplate jmsTemplate;    

    public void sendMessage(Destination destination, final Serializable obj) {
        jmsTemplate.send(destination, new MessageCreator() {
 
            public Message createMessage(Session session) throws JMSException {
                ObjectMessage objMessage = session.createObjectMessage(obj);
                return objMessage;
            }
            
        });
    }
 
}
    

?????? 這是對應(yīng)的在沒有使用 MessageConverter 的時候我們需要 new 一個 MessageCreator 接口對象,然后在其抽象方法 createMessage 內(nèi)部使用 session 創(chuàng)建一個對應(yīng)的消息。在使用了 MessageConverter 的時候我們在使用 JmsTemplate 進行消息發(fā)送時只需要調(diào)用其對應(yīng)的 convertAndSend 方法即可。如:

?

          public void sendMessage(Destination destination, final Serializable obj) {
        //未使用MessageConverter的情況
        /*jmsTemplate.send(destination, new MessageCreator() {
 
            public Message createMessage(Session session) throws JMSException {
                ObjectMessage objMessage = session.createObjectMessage(obj);
                return objMessage;
            }
            
        });*/
        //使用MessageConverter的情況
        jmsTemplate.convertAndSend(destination, obj);
    }
    

這樣 JmsTemplate 就會在其內(nèi)部調(diào)用預(yù)定的 MessageConverter 對我們的消息對象進行轉(zhuǎn)換,然后再進行發(fā)送。

?????? 這個時候我們就需要定義我們的 MessageConverter 了。要定義自己的 MessageConverter 很簡單,只需要實現(xiàn) Spring 為我們提供的 MessageConverter 接口即可。我們先來看一下 MessageConverter 接口的定義:

      public interface MessageConverter {
 
    Message toMessage(Object object, Session session) throws JMSException, MessageConversionException;
 
    Object fromMessage(Message message) throws JMSException, MessageConversionException;
 
}
    

?????? 我們可以看到其中一共定義了兩個方法 fromMessage toMessage fromMessage 是用來把一個 JMS Message 轉(zhuǎn)換成對應(yīng)的 Java 對象,而 toMessage 方法是用來把一個 Java 對象轉(zhuǎn)換成對應(yīng)的 JMS Message 。因為我們已經(jīng)知道上面要發(fā)送的對象就是一個 Email 對象,所以在這里我們就簡單地定義一個 EmailMessageConverter 用來把 Email 對象和對應(yīng)的 ObjectMessage 進行轉(zhuǎn)換,其代碼如下:

?

      import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import javax.jms.Session;
 
import org.springframework.jms.support.converter.MessageConversionException;
import org.springframework.jms.support.converter.MessageConverter;
 
public class EmailMessageConverter implements MessageConverter {
 
    public Message toMessage(Object object, Session session)
            throws JMSException, MessageConversionException {
        return session.createObjectMessage((Serializable) object);
    }
 
    public Object fromMessage(Message message) throws JMSException,
            MessageConversionException {
        ObjectMessage objMessage = (ObjectMessage) message;
        return objMessage.getObject();
    }
 
}

    

?

?????? 這樣當我們利用 JmsTemplate convertAndSend 方法發(fā)送一個 Email 對象的時候就會把對應(yīng)的 Email 對象當做參數(shù)調(diào)用我們定義好的 EmailMessageConverter toMessage 方法。

?????? 定義好我們的 EmailMessageConverter 之后就需要指定我們用來發(fā)送 Email 對象的 JmsTemplate 對象的 messageConverter EmailMessageConverter ,這里我們在 Spring 的配置文件中定義 JmsTemplate bean 的時候就指定:

?

          <!-- Spring提供的JMS工具類,它可以進行消息發(fā)送、接收等 -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <!-- 這個connectionFactory對應(yīng)的是我們定義的Spring提供的那個ConnectionFactory對象 -->
        <property name="connectionFactory" ref="connectionFactory"/>
        <!-- 消息轉(zhuǎn)換器 -->
        <property name="messageConverter" ref="emailMessageConverter"/>
    </bean>
    <!-- 類型轉(zhuǎn)換器 -->
    <bean id="emailMessageConverter" class="com.tiantian.springintejms.converter.EmailMessageConverter"/>

    

????

?????? 到此我們的 MessageConverter 就定義好了,也能夠進行使用了,接著我們來進行測試一下,定義測試代碼如下所示:

?

          @Test
    public void testObjectMessage() {
        Email email = new Email("zhangsan@xxx.com", "主題", "內(nèi)容");
        producerService.sendMessage(destination, email);
    }

    

?

?????? 上面 destination 對應(yīng)的接收處理的 MessageListener 方法如下所示:

?

      public class ConsumerMessageListener implements MessageListener {
 
    public void onMessage(Message message) {
        
        if (message instanceof ObjectMessage) {
            ObjectMessage objMessage = (ObjectMessage) message;
            try {
                Object obj = objMessage.getObject();
                Email email = (Email) obj;
                System.out.println("接收到一個ObjectMessage,包含Email對象。");
                System.out.println(email);
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
 
}

    

?

?????? 之前說了 MessageConverter 有兩方面的功能,除了把 Java 對象轉(zhuǎn)換成對應(yīng)的 Jms Message 之外還可以把 Jms Message 轉(zhuǎn)換成對應(yīng)的 Java 對象。我們看上面的消息監(jiān)聽器在接收消息的時候接收到的就是一個 Jms Message ,如果我們要利用 MessageConverter 來把它轉(zhuǎn)換成對應(yīng)的 Java 對象的話,只能是我們往里面注入一個對應(yīng)的 MessageConverter ,然后在里面手動的調(diào)用,如:

?

      public class ConsumerMessageListener implements MessageListener {
 
    private MessageConverter messageConverter;
    
    public void onMessage(Message message) {
        
        if (message instanceof ObjectMessage) {
            ObjectMessage objMessage = (ObjectMessage) message;
            try {
                /*Object obj = objMessage.getObject();
                Email email = (Email) obj;*/
                Email email = (Email) messageConverter.fromMessage(objMessage);
                System.out.println("接收到一個ObjectMessage,包含Email對象。");
                System.out.println(email);
            } catch (JMSException e) {
                e.printStackTrace();
            }
            
        }
    }
 
    public MessageConverter getMessageConverter() {
        return messageConverter;
    }
 
    public void setMessageConverter(MessageConverter messageConverter) {
        this.messageConverter = messageConverter;
    }
 
}

    

?

?????? 當我們使用 MessageListenerAdapter 來作為消息監(jiān)聽器的時候,我們可以為它指定一個對應(yīng)的 MessageConverter ,這樣 Spring 在處理接收到的消息的時候就會自動地利用我們指定的 MessageConverter 對它進行轉(zhuǎn)換,然后把轉(zhuǎn)換后的 Java 對象作為參數(shù)調(diào)用指定的消息處理方法。這里我們再把前面講解 MessageListenerAdapter 時定義的 MessageListenerAdapter 拿來做一個測試,我們指定它的 MessageConverter 為我們定義好的 EmailMessageConverter

?

          <!-- 消息監(jiān)聽適配器 -->
    <bean id="messageListenerAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
        <property name="delegate">
            <bean class="com.tiantian.springintejms.listener.ConsumerListener"/>
        </property>
        <property name="defaultListenerMethod" value="receiveMessage"/>
        <property name="messageConverter" ref="emailMessageConverter"/>
    </bean>
    <!-- 消息監(jiān)聽適配器對應(yīng)的監(jiān)聽容器 -->
    <bean id="messageListenerAdapterContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="destination" ref="adapterQueue"/>
        <property name="messageListener" ref="messageListenerAdapter"/><!-- 使用MessageListenerAdapter來作為消息監(jiān)聽器 -->
    </bean>

    

?

?????? 然后在我們的真正用于處理接收到的消息的 ConsumerListener 中添加一個 receiveMessage 方法,添加后其代碼如下所示:

?

      public class ConsumerListener {
 
    public void receiveMessage(String message) {
        System.out.println("ConsumerListener通過receiveMessage接收到一個純文本消息,消息內(nèi)容是:" + message);
    }
    
    public void receiveMessage(Email email) {
        System.out.println("接收到一個包含Email的ObjectMessage。");
        System.out.println(email);
    }
    
}

    

?

?????? 然后我們定義如下測試代碼:

?

          @Test
    public void testObjectMessage() {
        Email email = new Email("zhangsan@xxx.com", "主題", "內(nèi)容");
        producerService.sendMessage(adapterQueue, email);
    }


    

?

?????? 因為我們給 MessageListenerAdapter 指定了一個 MessageConverter ,而且是一個 EmailMessageConverter ,所以當 MessageListenerAdapter 接收到一個消息后,它會調(diào)用我們指定的 MessageConverter fromMessage 方法把它轉(zhuǎn)換成一個 Java 對象,根據(jù)定義這里會轉(zhuǎn)換成一個 Email 對象,然后會把這個 Email 對象作為參數(shù)調(diào)用我們通過 defaultListenerMethod 屬性指定的默認處理器方法,根據(jù)定義這里就是 receiveMessage 方法,但是我們可以看到在 ConsumerListener 中我們一共定義了兩個 receiveMessage 方法,因為是通過轉(zhuǎn)換后的 Email 對象作為參數(shù)進行方法調(diào)用的,所以這里調(diào)用的就應(yīng)該是參數(shù)類型為 Email receiveMessage 方法了。上述測試代碼運行后會輸出如下結(jié)果:

???????
說到這里可能有讀者就會有疑問了,說我們在之前講解 MessageListenerAdapter 的時候不是沒有指定對應(yīng)的 MessageConverter ,然后發(fā)送了一個 TextMessage ,結(jié)果 Spring 還是把它轉(zhuǎn)換成一個 String 對象,調(diào)用了 ConsumerListener 參數(shù)類型為 String receiveMessage 方法嗎?那你這個 MessageConverter MessageListenerAdapter 進行消息接收的時候也沒什么用啊。

?????? 其實還是有用的,在我們使用 MessageListenerAdapter 時,在對其進行初始化也就是調(diào)用其構(gòu)造方法時,它會默認 new 一個 Spring 已經(jīng)為我們實現(xiàn)了的 MessageConverter —— SimpleMessageConverter 作為其默認的 MessageConverter ,這也就是為什么我們在使用 MessageListenerAdapter 的時候不需要指定 MessageConverter 但是消息還是會轉(zhuǎn)換成對應(yīng)的 Java 對象的原因。所以默認情況下我們使用 MessageListenerAdapter 時其對應(yīng)的 MessageListener 的處理器方法參數(shù)類型必須是一個普通 Java 對象,而不能是對應(yīng)的 Jms Message 對象。

?????? 那如果我們在處理 Jms Message 的時候想使用 MessageListenerAdapter ,然后又希望處理最原始的 Message ,而不是經(jīng)過 MessageConverter 進行轉(zhuǎn)換后的 Message 該怎么辦呢?這個時候我們只需要在定義 MessageListenerAdapter 的時候指定其 MessageConverter 為空就可以了。

?

          <!-- 消息監(jiān)聽適配器 -->
    <bean id="messageListenerAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
        <property name="delegate">
            <bean class="com.tiantian.springintejms.listener.ConsumerListener"/>
        </property>
        <property name="defaultListenerMethod" value="receiveMessage"/>
        <property name="messageConverter">
            <null/>
        </property>
    </bean>

    

?

?????? 那么這個時候我們的真實 MessageListener 的處理器方法參數(shù)類型就應(yīng)該是 Jms Message 或?qū)?yīng)的 Jms Message 子類型了,不然就會調(diào)用不到對應(yīng)的處理方法了。這里因為我們發(fā)送的是一個 ObjectMessage ,所以這里就添加一個對應(yīng)的參數(shù)類型為 ObjectMessage receiveMessage 方法了。

?

          public void receiveMessage(ObjectMessage message) throws JMSException {
        System.out.println(message.getObject());
    }

    

?

?????? 剛剛講到 Spring 已經(jīng)為我們實現(xiàn)了一個簡單的 MessageConverter ,即 org.springframework.jms.support.converter.SimpleMessageConverter ,其實 Spring 在初始化 JmsTemplate 的時候也指定了其對應(yīng)的 MessageConverter 為一個 SimpleMessageConverter ,所以如果我們平常沒有什么特殊要求的時候可以直接使用 JmsTemplate convertAndSend 系列方法進行消息發(fā)送,而不必繁瑣的在調(diào)用 send 方法時自己 new 一個 MessageCreator 進行相應(yīng) Message 的創(chuàng)建。

這里我們也來看一下 SimpleMessageConverter 的定義,如果覺得它不能滿足你的要求,那我們可以對它里面的部分方法進行重寫,或者是完全實現(xiàn)自己的 MessageConverter

      public class SimpleMessageConverter implements MessageConverter {
 
    public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
        if (object instanceof Message) {
            return (Message) object;
        }
        else if (object instanceof String) {
            return createMessageForString((String) object, session);
        }
        else if (object instanceof byte[]) {
            return createMessageForByteArray((byte[]) object, session);
        }
        else if (object instanceof Map) {
            return createMessageForMap((Map) object, session);
        }
        else if (object instanceof Serializable) {
            return createMessageForSerializable(((Serializable) object), session);
        }

        else {
            throw new MessageConversionException("Cannot convert object of type [" +
                    ObjectUtils.nullSafeClassName(object) + "] to JMS message. Supported message " +
                    "payloads are: String, byte array, Map<String,?>, Serializable object.");
        }
    }
 
    public Object fromMessage(Message message) throws JMSException, MessageConversionException {
        if (message instanceof TextMessage) {
            return extractStringFromMessage((TextMessage) message);
        }
        else if (message instanceof BytesMessage) {
            return extractByteArrayFromMessage((BytesMessage) message);
        }
        else if (message instanceof MapMessage) {
            return extractMapFromMessage((MapMessage) message);
        }
        else if (message instanceof ObjectMessage) {
            return extractSerializableFromMessage((ObjectMessage) message);
        }
        else {
            return message;
        }
    }
 
    protected TextMessage createMessageForString(String text, Session session) throws JMSException {
        return session.createTextMessage(text);
    }
 
    protected BytesMessage createMessageForByteArray(byte[] bytes, Session session) throws JMSException {
        BytesMessage message = session.createBytesMessage();
        message.writeBytes(bytes);
        return message;
    }
 
    protected MapMessage createMessageForMap(Map<?, ?> map, Session session) throws JMSException {
        MapMessage message = session.createMapMessage();
        for (Map.Entry entry : map.entrySet()) {
            if (!(entry.getKey() instanceof String)) {
                throw new MessageConversionException("Cannot convert non-String key of type [" +
                        ObjectUtils.nullSafeClassName(entry.getKey()) + "] to JMS MapMessage entry");
            }
            message.setObject((String) entry.getKey(), entry.getValue());
        }
        return message;
    }
 
    protected ObjectMessage createMessageForSerializable(Serializable object, Session session) throws JMSException {
        return session.createObjectMessage(object);
    }
 
 
    protected String extractStringFromMessage(TextMessage message) throws JMSException {
        return message.getText();
    }
 
    protected byte[] extractByteArrayFromMessage(BytesMessage message) throws JMSException {
        byte[] bytes = new byte[(int) message.getBodyLength()];
        message.readBytes(bytes);
        return bytes;
    }
 
    protected Map extractMapFromMessage(MapMessage message) throws JMSException {
        Map<String, Object> map = new HashMap<String, Object>();
        Enumeration en = message.getMapNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            map.put(key, message.getObject(key));
        }
        return map;
    }
 
    protected Serializable extractSerializableFromMessage(ObjectMessage message) throws JMSException {
        return message.getObject();
    }
 
}

    

附:

?

Spring整合JMS(三)——MessageConverter介紹


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日本欧美一区二区三区视频麻豆 | 免费播放春色aⅴ视频 | 免费看片网址 | 日韩一区精品 | www成人国产在线观看网站 | 日本精品视频在线播放 | 四虎图库 | 一区二区三区在线 | 五月婷婷色综合 | 91免费国产 | 日本无码免费久久久精品 | 久久久久久亚洲精品 | 国产在线精品一区二区高清不卡 | 精品国产视频在线观看 | 污视频在线免费 | 我要看免费毛片 | 91麻豆精品一二三区在线 | 91麻豆精品国产91久久久久久 | 国产精品毛片一区二区三区 | 久草在线播放 | 四虎影院新地址 | 亚洲精品久久久久久蜜臀 | 激情小说色 | 五月婷婷综合激情网 | 成人免费播放视频777777 | 男女进进出出动态图啪啪 | 亚洲a级在线观看 | 免费在线日韩 | 久久久大片| 91精品国产综合久久福利 | 91社区影院 | 草草线在成人免费视频 | 一级色毛片 | 国产一二三四区中 | 黄色网在线播放 | 国产精品综合视频 | 国产成人久久 | 青娱乐在线免费 | 奇米第四色在线 | av免费观看网站 | 我和我的祖国电影在线观看免费版高清 |