001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jms.support.converter; 018 019import java.io.Serializable; 020import java.util.Enumeration; 021import java.util.HashMap; 022import java.util.Map; 023 024import javax.jms.BytesMessage; 025import javax.jms.JMSException; 026import javax.jms.MapMessage; 027import javax.jms.Message; 028import javax.jms.ObjectMessage; 029import javax.jms.Session; 030import javax.jms.TextMessage; 031 032import org.springframework.util.ObjectUtils; 033 034/** 035 * A simple message converter which is able to handle TextMessages, BytesMessages, 036 * MapMessages, and ObjectMessages. Used as default conversion strategy 037 * by {@link org.springframework.jms.core.JmsTemplate}, for 038 * {@code convertAndSend} and {@code receiveAndConvert} operations. 039 * 040 * <p>Converts a String to a {@link javax.jms.TextMessage}, a byte array to a 041 * {@link javax.jms.BytesMessage}, a Map to a {@link javax.jms.MapMessage}, and 042 * a Serializable object to a {@link javax.jms.ObjectMessage} (or vice versa). 043 * 044 * @author Juergen Hoeller 045 * @since 1.1 046 * @see org.springframework.jms.core.JmsTemplate#convertAndSend 047 * @see org.springframework.jms.core.JmsTemplate#receiveAndConvert 048 */ 049public class SimpleMessageConverter implements MessageConverter { 050 051 /** 052 * This implementation creates a TextMessage for a String, a 053 * BytesMessage for a byte array, a MapMessage for a Map, 054 * and an ObjectMessage for a Serializable object. 055 * @see #createMessageForString 056 * @see #createMessageForByteArray 057 * @see #createMessageForMap 058 * @see #createMessageForSerializable 059 */ 060 @Override 061 public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { 062 if (object instanceof Message) { 063 return (Message) object; 064 } 065 else if (object instanceof String) { 066 return createMessageForString((String) object, session); 067 } 068 else if (object instanceof byte[]) { 069 return createMessageForByteArray((byte[]) object, session); 070 } 071 else if (object instanceof Map) { 072 return createMessageForMap((Map<? ,?>) object, session); 073 } 074 else if (object instanceof Serializable) { 075 return createMessageForSerializable(((Serializable) object), session); 076 } 077 else { 078 throw new MessageConversionException("Cannot convert object of type [" + 079 ObjectUtils.nullSafeClassName(object) + "] to JMS message. Supported message " + 080 "payloads are: String, byte array, Map<String,?>, Serializable object."); 081 } 082 } 083 084 /** 085 * This implementation converts a TextMessage back to a String, a 086 * ByteMessage back to a byte array, a MapMessage back to a Map, 087 * and an ObjectMessage back to a Serializable object. Returns 088 * the plain Message object in case of an unknown message type. 089 * @see #extractStringFromMessage 090 * @see #extractByteArrayFromMessage 091 * @see #extractMapFromMessage 092 * @see #extractSerializableFromMessage 093 */ 094 @Override 095 public Object fromMessage(Message message) throws JMSException, MessageConversionException { 096 if (message instanceof TextMessage) { 097 return extractStringFromMessage((TextMessage) message); 098 } 099 else if (message instanceof BytesMessage) { 100 return extractByteArrayFromMessage((BytesMessage) message); 101 } 102 else if (message instanceof MapMessage) { 103 return extractMapFromMessage((MapMessage) message); 104 } 105 else if (message instanceof ObjectMessage) { 106 return extractSerializableFromMessage((ObjectMessage) message); 107 } 108 else { 109 return message; 110 } 111 } 112 113 114 /** 115 * Create a JMS TextMessage for the given String. 116 * @param text the String to convert 117 * @param session current JMS session 118 * @return the resulting message 119 * @throws JMSException if thrown by JMS methods 120 * @see javax.jms.Session#createTextMessage 121 */ 122 protected TextMessage createMessageForString(String text, Session session) throws JMSException { 123 return session.createTextMessage(text); 124 } 125 126 /** 127 * Create a JMS BytesMessage for the given byte array. 128 * @param bytes the byte array to convert 129 * @param session current JMS session 130 * @return the resulting message 131 * @throws JMSException if thrown by JMS methods 132 * @see javax.jms.Session#createBytesMessage 133 */ 134 protected BytesMessage createMessageForByteArray(byte[] bytes, Session session) throws JMSException { 135 BytesMessage message = session.createBytesMessage(); 136 message.writeBytes(bytes); 137 return message; 138 } 139 140 /** 141 * Create a JMS MapMessage for the given Map. 142 * @param map the Map to convert 143 * @param session current JMS session 144 * @return the resulting message 145 * @throws JMSException if thrown by JMS methods 146 * @see javax.jms.Session#createMapMessage 147 */ 148 protected MapMessage createMessageForMap(Map<?, ?> map, Session session) throws JMSException { 149 MapMessage message = session.createMapMessage(); 150 for (Map.Entry<?, ?> entry : map.entrySet()) { 151 Object key = entry.getKey(); 152 if (!(key instanceof String)) { 153 throw new MessageConversionException("Cannot convert non-String key of type [" + 154 ObjectUtils.nullSafeClassName(key) + "] to JMS MapMessage entry"); 155 } 156 message.setObject((String) key, entry.getValue()); 157 } 158 return message; 159 } 160 161 /** 162 * Create a JMS ObjectMessage for the given Serializable object. 163 * @param object the Serializable object to convert 164 * @param session current JMS session 165 * @return the resulting message 166 * @throws JMSException if thrown by JMS methods 167 * @see javax.jms.Session#createObjectMessage 168 */ 169 protected ObjectMessage createMessageForSerializable(Serializable object, Session session) throws JMSException { 170 return session.createObjectMessage(object); 171 } 172 173 174 /** 175 * Extract a String from the given TextMessage. 176 * @param message the message to convert 177 * @return the resulting String 178 * @throws JMSException if thrown by JMS methods 179 */ 180 protected String extractStringFromMessage(TextMessage message) throws JMSException { 181 return message.getText(); 182 } 183 184 /** 185 * Extract a byte array from the given {@link BytesMessage}. 186 * @param message the message to convert 187 * @return the resulting byte array 188 * @throws JMSException if thrown by JMS methods 189 */ 190 protected byte[] extractByteArrayFromMessage(BytesMessage message) throws JMSException { 191 byte[] bytes = new byte[(int) message.getBodyLength()]; 192 message.readBytes(bytes); 193 return bytes; 194 } 195 196 /** 197 * Extract a Map from the given {@link MapMessage}. 198 * @param message the message to convert 199 * @return the resulting Map 200 * @throws JMSException if thrown by JMS methods 201 */ 202 @SuppressWarnings("unchecked") 203 protected Map<String, Object> extractMapFromMessage(MapMessage message) throws JMSException { 204 Map<String, Object> map = new HashMap<>(); 205 Enumeration<String> en = message.getMapNames(); 206 while (en.hasMoreElements()) { 207 String key = en.nextElement(); 208 map.put(key, message.getObject(key)); 209 } 210 return map; 211 } 212 213 /** 214 * Extract a Serializable object from the given {@link ObjectMessage}. 215 * @param message the message to convert 216 * @return the resulting Serializable object 217 * @throws JMSException if thrown by JMS methods 218 */ 219 protected Serializable extractSerializableFromMessage(ObjectMessage message) throws JMSException { 220 return message.getObject(); 221 } 222 223}