reworked JsonMessageConverter contribution into MappingJacksonMessageConverter, aligned with MappingJacksonHttpMessageConverter and MappingJacksonJsonView
This commit is contained in:
parent
8f69e81197
commit
098342918c
|
|
@ -1,143 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2010 the original author or authors. Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied. See the License for the specific language governing permissions and limitations under the
|
|
||||||
* License.
|
|
||||||
*/
|
|
||||||
package org.springframework.jms.support.converter;
|
|
||||||
|
|
||||||
import static org.codehaus.jackson.map.type.TypeFactory.collectionType;
|
|
||||||
import static org.codehaus.jackson.map.type.TypeFactory.mapType;
|
|
||||||
import static org.codehaus.jackson.map.type.TypeFactory.type;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import javax.jms.JMSException;
|
|
||||||
import javax.jms.Message;
|
|
||||||
|
|
||||||
import org.codehaus.jackson.type.JavaType;
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.util.ClassUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Default implementation of {@link JavaTypeMapper} using hard coded message
|
|
||||||
* properties to store and retrieve the content type information.
|
|
||||||
*
|
|
||||||
* @author Mark Pollack
|
|
||||||
* @author Sam Nelson
|
|
||||||
* @author Dave Syer
|
|
||||||
**/
|
|
||||||
public class DefaultJavaTypeMapper implements JavaTypeMapper, InitializingBean {
|
|
||||||
|
|
||||||
public static final String CLASSID_PROPERTY_NAME = "__TypeId__";
|
|
||||||
public static final String CONTENT_CLASSID_PROPERTY_NAME = "__ContentTypeId__";
|
|
||||||
public static final String KEY_CLASSID_PROPERTY_NAME = "__KeyTypeId__";
|
|
||||||
|
|
||||||
private Map<String, Class<?>> idClassMapping = new HashMap<String, Class<?>>();
|
|
||||||
private Map<Class<?>, String> classIdMapping = new HashMap<Class<?>, String>();
|
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
||||||
public JavaType toJavaType(Message message) throws JMSException {
|
|
||||||
JavaType classType = getClassIdType(retrieveHeader(message,
|
|
||||||
CLASSID_PROPERTY_NAME));
|
|
||||||
if (!classType.isContainerType()) {
|
|
||||||
return classType;
|
|
||||||
}
|
|
||||||
|
|
||||||
JavaType contentClassType = getClassIdType(retrieveHeader(message,
|
|
||||||
CONTENT_CLASSID_PROPERTY_NAME));
|
|
||||||
if (classType.getKeyType() == null) {
|
|
||||||
return collectionType(
|
|
||||||
(Class<? extends Collection>) classType.getRawClass(),
|
|
||||||
contentClassType);
|
|
||||||
}
|
|
||||||
|
|
||||||
JavaType keyClassType = getClassIdType(retrieveHeader(message,
|
|
||||||
KEY_CLASSID_PROPERTY_NAME));
|
|
||||||
JavaType mapType = mapType(
|
|
||||||
(Class<? extends Map>) classType.getRawClass(), keyClassType,
|
|
||||||
contentClassType);
|
|
||||||
return mapType;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private JavaType getClassIdType(String classId) {
|
|
||||||
if (this.idClassMapping.containsKey(classId)) {
|
|
||||||
return type(idClassMapping.get(classId));
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return type(ClassUtils
|
|
||||||
.forName(classId, getClass().getClassLoader()));
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new MessageConversionException(
|
|
||||||
"failed to resolve class name. Class not found [" + classId
|
|
||||||
+ "]", e);
|
|
||||||
} catch (LinkageError e) {
|
|
||||||
throw new MessageConversionException(
|
|
||||||
"failed to resolve class name. Linkage error [" + classId
|
|
||||||
+ "]", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String retrieveHeader(Message message, String headerName)
|
|
||||||
throws JMSException {
|
|
||||||
String classId = message.getStringProperty(headerName);
|
|
||||||
if (classId == null) {
|
|
||||||
throw new MessageConversionException(
|
|
||||||
"failed to convert Message content. Could not resolve "
|
|
||||||
+ headerName + " in header");
|
|
||||||
}
|
|
||||||
return classId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIdClassMapping(Map<String, Class<?>> idClassMapping) {
|
|
||||||
this.idClassMapping = idClassMapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fromJavaType(JavaType javaType, Message message)
|
|
||||||
throws JMSException {
|
|
||||||
addHeader(message, CLASSID_PROPERTY_NAME,
|
|
||||||
(Class<?>) javaType.getRawClass());
|
|
||||||
|
|
||||||
if (javaType.isContainerType()) {
|
|
||||||
addHeader(message, CONTENT_CLASSID_PROPERTY_NAME, javaType
|
|
||||||
.getContentType().getRawClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (javaType.getKeyType() != null) {
|
|
||||||
addHeader(message, KEY_CLASSID_PROPERTY_NAME, javaType.getKeyType()
|
|
||||||
.getRawClass());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
|
||||||
validateIdTypeMapping();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addHeader(Message message, String headerName, Class<?> clazz)
|
|
||||||
throws JMSException {
|
|
||||||
if (classIdMapping.containsKey(clazz)) {
|
|
||||||
message.setStringProperty(headerName, classIdMapping.get(clazz));
|
|
||||||
} else {
|
|
||||||
message.setStringProperty(headerName, clazz.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validateIdTypeMapping() {
|
|
||||||
Map<String, Class<?>> finalIdClassMapping = new HashMap<String, Class<?>>();
|
|
||||||
for (Entry<String, Class<?>> entry : idClassMapping.entrySet()) {
|
|
||||||
String id = entry.getKey();
|
|
||||||
Class<?> clazz = entry.getValue();
|
|
||||||
finalIdClassMapping.put(id, clazz);
|
|
||||||
classIdMapping.put(clazz, id);
|
|
||||||
}
|
|
||||||
this.idClassMapping = finalIdClassMapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2010 the original author or authors. Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
||||||
* either express or implied. See the License for the specific language governing permissions and limitations under the
|
|
||||||
* License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.jms.support.converter;
|
|
||||||
|
|
||||||
import javax.jms.JMSException;
|
|
||||||
import javax.jms.Message;
|
|
||||||
|
|
||||||
import org.codehaus.jackson.type.JavaType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Strategy for setting metadata on messages such that one can create the class that needs to be instantiated when
|
|
||||||
* receiving a message.
|
|
||||||
*
|
|
||||||
* @author Dave Syer
|
|
||||||
* @author Sam Nelson
|
|
||||||
*/
|
|
||||||
public interface JavaTypeMapper {
|
|
||||||
|
|
||||||
void fromJavaType(JavaType javaType, Message message) throws JMSException;
|
|
||||||
|
|
||||||
JavaType toJavaType(Message message) throws JMSException;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,359 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2010 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.jms.support.converter;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
|
|
||||||
import javax.jms.BytesMessage;
|
|
||||||
import javax.jms.JMSException;
|
|
||||||
import javax.jms.Message;
|
|
||||||
import javax.jms.Session;
|
|
||||||
import javax.jms.TextMessage;
|
|
||||||
import javax.xml.transform.Result;
|
|
||||||
|
|
||||||
import org.codehaus.jackson.JsonParseException;
|
|
||||||
import org.codehaus.jackson.map.DeserializationConfig;
|
|
||||||
import org.codehaus.jackson.map.JsonMappingException;
|
|
||||||
import org.codehaus.jackson.map.ObjectMapper;
|
|
||||||
import org.codehaus.jackson.map.type.TypeFactory;
|
|
||||||
import org.codehaus.jackson.type.JavaType;
|
|
||||||
import org.springframework.oxm.Marshaller;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Message converter that uses the Jackson library to convert messages to and
|
|
||||||
* from JSON. Maps an object to a {@link BytesMessage}, or to a
|
|
||||||
* {@link TextMessage} if the {@link #setTargetType marshalTo} is set to
|
|
||||||
* {@link MessageType#TEXT}. Converts from a {@link TextMessage} or
|
|
||||||
* {@link BytesMessage} to an object.
|
|
||||||
*
|
|
||||||
* @author Mark Pollack
|
|
||||||
* @author James Carr
|
|
||||||
* @author Dave Syer
|
|
||||||
*/
|
|
||||||
public class JsonMessageConverter implements MessageConverter {
|
|
||||||
|
|
||||||
public static final String DEFAULT_CHARSET = "UTF-8";
|
|
||||||
|
|
||||||
public static final String DEFAULT_ENCODING_PROPERTY_NAME = "__Encoding__";
|
|
||||||
|
|
||||||
private volatile String defaultCharset = DEFAULT_CHARSET;
|
|
||||||
|
|
||||||
private MessageType targetType = MessageType.BYTES;
|
|
||||||
|
|
||||||
private ObjectMapper jsonObjectMapper = new ObjectMapper();
|
|
||||||
|
|
||||||
private JavaTypeMapper javaTypeMapper = new DefaultJavaTypeMapper();
|
|
||||||
|
|
||||||
private String encodingPropertyName = DEFAULT_ENCODING_PROPERTY_NAME;
|
|
||||||
|
|
||||||
public JsonMessageConverter() {
|
|
||||||
super();
|
|
||||||
initializeJsonObjectMapper();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify whether {@link #toMessage(Object, Session)} should marshal to a
|
|
||||||
* {@link BytesMessage} or a {@link TextMessage}.
|
|
||||||
* <p>
|
|
||||||
* The default is {@link MessageType#BYTES}, i.e. this converter marshals to
|
|
||||||
* a {@link BytesMessage}. Note that the default version of this converter
|
|
||||||
* supports {@link MessageType#BYTES} and {@link MessageType#TEXT} only.
|
|
||||||
*
|
|
||||||
* @see MessageType#BYTES
|
|
||||||
* @see MessageType#TEXT
|
|
||||||
*/
|
|
||||||
public void setTargetType(MessageType targetType) {
|
|
||||||
this.targetType = targetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A mapper to extract a Jackson {@link JavaType} from a message.
|
|
||||||
*
|
|
||||||
* @param javaTypeMapper
|
|
||||||
* the javaTypeMapper to set
|
|
||||||
*/
|
|
||||||
public void setJavaTypeMapper(JavaTypeMapper javaTypeMapper) {
|
|
||||||
this.javaTypeMapper = javaTypeMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify the default charset to use when converting from and from
|
|
||||||
* text-based Message body content. If not specified, the charset will be
|
|
||||||
* "UTF-8".
|
|
||||||
*/
|
|
||||||
public void setDefaultCharset(String defaultCharset) {
|
|
||||||
this.defaultCharset = (defaultCharset != null) ? defaultCharset
|
|
||||||
: DEFAULT_CHARSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specify the name of the JMS message property that carries the encoding
|
|
||||||
* from bytes to String and back is BytesMessage is used during the
|
|
||||||
* conversion process.
|
|
||||||
*
|
|
||||||
* @param encodingPropertyName
|
|
||||||
* the name of the message property
|
|
||||||
*/
|
|
||||||
public void setEncodingPropertyName(String encodingPropertyName) {
|
|
||||||
this.encodingPropertyName = encodingPropertyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link ObjectMapper} to use instead of using the default. An
|
|
||||||
* alternative to injecting a mapper is to extend this class and override
|
|
||||||
* {@link #initializeJsonObjectMapper()}.
|
|
||||||
*
|
|
||||||
* @param jsonObjectMapper
|
|
||||||
* the object mapper to set
|
|
||||||
*/
|
|
||||||
public void setJsonObjectMapper(ObjectMapper jsonObjectMapper) {
|
|
||||||
this.jsonObjectMapper = jsonObjectMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subclass and override to customize the mapper.
|
|
||||||
*/
|
|
||||||
protected void initializeJsonObjectMapper() {
|
|
||||||
jsonObjectMapper
|
|
||||||
.configure(
|
|
||||||
DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message toMessage(Object object, Session session)
|
|
||||||
throws JMSException, MessageConversionException {
|
|
||||||
Message message;
|
|
||||||
try {
|
|
||||||
switch (this.targetType) {
|
|
||||||
case TEXT:
|
|
||||||
message = mapToTextMessage(object, session,
|
|
||||||
this.jsonObjectMapper);
|
|
||||||
break;
|
|
||||||
case BYTES:
|
|
||||||
message = mapToBytesMessage(object, session,
|
|
||||||
this.jsonObjectMapper);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
message = mapToMessage(object, session, this.jsonObjectMapper,
|
|
||||||
this.targetType);
|
|
||||||
}
|
|
||||||
} catch (JsonMappingException ex) {
|
|
||||||
throw new MessageConversionException("Could not map [" + object
|
|
||||||
+ "]", ex);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new MessageConversionException("Could not map [" + object
|
|
||||||
+ "]", ex);
|
|
||||||
}
|
|
||||||
javaTypeMapper.fromJavaType(TypeFactory.type(object.getClass()),
|
|
||||||
message);
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map the given object to a {@link TextMessage}.
|
|
||||||
* @param object the object to be mapped
|
|
||||||
* @param session current JMS session
|
|
||||||
* @param jsonObjectMapper the mapper to use
|
|
||||||
* @return the resulting message
|
|
||||||
* @throws JMSException if thrown by JMS methods
|
|
||||||
* @throws IOException in case of I/O errors
|
|
||||||
* @throws JsonMappingException in case of Jackson mapping errors
|
|
||||||
* @see Session#createBytesMessage
|
|
||||||
* @see Marshaller#marshal(Object, Result)
|
|
||||||
*/
|
|
||||||
protected Message mapToTextMessage(Object object, Session session,
|
|
||||||
ObjectMapper jsonObjectMapper) throws JsonMappingException,
|
|
||||||
IOException, JMSException {
|
|
||||||
StringWriter writer = new StringWriter();
|
|
||||||
jsonObjectMapper.writeValue(writer, object);
|
|
||||||
return session.createTextMessage(writer.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Map the given object to a {@link BytesMessage}.
|
|
||||||
* @param object the object to be mapped
|
|
||||||
* @param session current JMS session
|
|
||||||
* @param jsonObjectMapper the mapper to use
|
|
||||||
* @return the resulting message
|
|
||||||
* @throws JMSException if thrown by JMS methods
|
|
||||||
* @throws IOException in case of I/O errors
|
|
||||||
* @throws JsonMappingException in case of Jackson mapping errors
|
|
||||||
* @see Session#createBytesMessage
|
|
||||||
* @see Marshaller#marshal(Object, Result)
|
|
||||||
*/
|
|
||||||
protected Message mapToBytesMessage(Object object, Session session,
|
|
||||||
ObjectMapper jsonObjectMapper) throws JsonMappingException,
|
|
||||||
IOException, JMSException {
|
|
||||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
||||||
OutputStreamWriter writer = new OutputStreamWriter(bos, defaultCharset);
|
|
||||||
jsonObjectMapper.writeValue(writer, object);
|
|
||||||
BytesMessage message = session.createBytesMessage();
|
|
||||||
message.writeBytes(bos.toByteArray());
|
|
||||||
message.setStringProperty(encodingPropertyName, defaultCharset);
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template method that allows for custom message mapping. Invoked when
|
|
||||||
* {@link #setTargetType} is not {@link MessageType#TEXT} or
|
|
||||||
* {@link MessageType#BYTES}.
|
|
||||||
* <p>
|
|
||||||
* The default implementation throws an {@link IllegalArgumentException}.
|
|
||||||
*
|
|
||||||
* @param object
|
|
||||||
* the object to marshal
|
|
||||||
* @param session
|
|
||||||
* the JMS session
|
|
||||||
* @param jsonObjectMapper
|
|
||||||
* the mapper to use
|
|
||||||
* @param targetType
|
|
||||||
* the target message type (other than TEXT or BYTES)
|
|
||||||
* @return the resulting message
|
|
||||||
* @throws JMSException
|
|
||||||
* if thrown by JMS methods
|
|
||||||
* @throws IOException
|
|
||||||
* in case of I/O errors
|
|
||||||
* @throws JsonMappingException
|
|
||||||
* in case of Jackson mapping errors
|
|
||||||
*/
|
|
||||||
protected Message mapToMessage(Object object, Session session,
|
|
||||||
ObjectMapper jsonObjectMapper, MessageType targetType)
|
|
||||||
throws JsonMappingException, IOException, JMSException {
|
|
||||||
throw new IllegalArgumentException("Unsupported message type ["
|
|
||||||
+ targetType + "]. Cannot map to the specified message type.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object fromMessage(Message message) throws JMSException,
|
|
||||||
MessageConversionException {
|
|
||||||
Object content = null;
|
|
||||||
try {
|
|
||||||
JavaType targetJavaType = javaTypeMapper.toJavaType(message);
|
|
||||||
content = convertToObject(message, targetJavaType);
|
|
||||||
} catch (JsonParseException e) {
|
|
||||||
throw new MessageConversionException(
|
|
||||||
"Failed to convert Message content", e);
|
|
||||||
} catch (JsonMappingException e) {
|
|
||||||
throw new MessageConversionException(
|
|
||||||
"Failed to convert Message content", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new MessageConversionException(
|
|
||||||
"Failed to convert Message content", e);
|
|
||||||
}
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenience method to dispatch to converters for individual message
|
|
||||||
* types.
|
|
||||||
*/
|
|
||||||
private Object convertToObject(Message message, JavaType targetJavaType)
|
|
||||||
throws JMSException, JsonParseException, JsonMappingException,
|
|
||||||
IOException {
|
|
||||||
if (message instanceof TextMessage) {
|
|
||||||
return convertFromTextMessage((TextMessage) message, targetJavaType);
|
|
||||||
} else if (message instanceof BytesMessage) {
|
|
||||||
return convertFromBytesMessage((BytesMessage) message,
|
|
||||||
targetJavaType);
|
|
||||||
} else {
|
|
||||||
return convertFromMessage(message, targetJavaType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a generic Message to a Java Object with the specified type.
|
|
||||||
* Default implementation throws IllegalArgumentException.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* the input message
|
|
||||||
* @param targetJavaType
|
|
||||||
* the target type
|
|
||||||
* @return the message converted to an object
|
|
||||||
* @throws JsonParseException
|
|
||||||
* if thrown by Jackson
|
|
||||||
* @throws JsonMappingException
|
|
||||||
* if thrown by Jackson
|
|
||||||
* @throws IOException
|
|
||||||
* in case of I/O errors
|
|
||||||
* @throws JMSException
|
|
||||||
* if thrown by JMS
|
|
||||||
*/
|
|
||||||
protected Object convertFromMessage(Message message, JavaType targetJavaType) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"JsonMessageConverter only supports TextMessages and BytesMessages");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a TextMessage to a Java Object with the specified type.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* the input message
|
|
||||||
* @param targetJavaType
|
|
||||||
* the target type
|
|
||||||
* @return the message converted to an object
|
|
||||||
* @throws JsonParseException
|
|
||||||
* if thrown by Jackson
|
|
||||||
* @throws JsonMappingException
|
|
||||||
* if thrown by Jackson
|
|
||||||
* @throws IOException
|
|
||||||
* in case of I/O errors
|
|
||||||
* @throws JMSException
|
|
||||||
* if thrown by JMS
|
|
||||||
*/
|
|
||||||
protected Object convertFromTextMessage(TextMessage message,
|
|
||||||
JavaType targetJavaType) throws JsonParseException,
|
|
||||||
JsonMappingException, IOException, JMSException {
|
|
||||||
String body = message.getText();
|
|
||||||
return jsonObjectMapper.readValue(body, targetJavaType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a BytesMessage to a Java Object with the specified type.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* the input message
|
|
||||||
* @param targetJavaType
|
|
||||||
* the target type
|
|
||||||
* @return the message converted to an object
|
|
||||||
* @throws JsonParseException
|
|
||||||
* if thrown by Jackson
|
|
||||||
* @throws JsonMappingException
|
|
||||||
* if thrown by Jackson
|
|
||||||
* @throws IOException
|
|
||||||
* in case of I/O errors
|
|
||||||
* @throws JMSException
|
|
||||||
* if thrown by JMS
|
|
||||||
*/
|
|
||||||
protected Object convertFromBytesMessage(BytesMessage message,
|
|
||||||
JavaType targetJavaType) throws JsonParseException,
|
|
||||||
JsonMappingException, IOException, JMSException {
|
|
||||||
String encoding = defaultCharset;
|
|
||||||
if (message.propertyExists(encodingPropertyName)) {
|
|
||||||
encoding = message.getStringProperty(encodingPropertyName);
|
|
||||||
}
|
|
||||||
byte[] bytes = new byte[(int) message.getBodyLength()];
|
|
||||||
message.readBytes(bytes);
|
|
||||||
try {
|
|
||||||
String body = new String(bytes, encoding);
|
|
||||||
return jsonObjectMapper.readValue(body, targetJavaType);
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
throw new MessageConversionException(
|
|
||||||
"Cannot convert bytes to String", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,373 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2011 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.jms.support.converter;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.jms.BytesMessage;
|
||||||
|
import javax.jms.JMSException;
|
||||||
|
import javax.jms.Message;
|
||||||
|
import javax.jms.Session;
|
||||||
|
import javax.jms.TextMessage;
|
||||||
|
import javax.xml.transform.Result;
|
||||||
|
|
||||||
|
import org.codehaus.jackson.map.ObjectMapper;
|
||||||
|
import org.codehaus.jackson.map.type.TypeFactory;
|
||||||
|
import org.codehaus.jackson.type.JavaType;
|
||||||
|
|
||||||
|
import org.springframework.oxm.Marshaller;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message converter that uses the Jackson library to convert messages to and from JSON.
|
||||||
|
* Maps an object to a {@link BytesMessage}, or to a {@link TextMessage} if the
|
||||||
|
* {@link #setTargetType marshalTo} is set to {@link MessageType#TEXT}.
|
||||||
|
* Converts from a {@link TextMessage} or {@link BytesMessage} to an object.
|
||||||
|
*
|
||||||
|
* @author Mark Pollack
|
||||||
|
* @author Dave Syer
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class MappingJacksonMessageConverter implements MessageConverter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default encoding used for writing to text messages: UTF-8.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_ENCODING = "UTF-8";
|
||||||
|
|
||||||
|
|
||||||
|
private ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
private MessageType targetType = MessageType.BYTES;
|
||||||
|
|
||||||
|
private String encoding = DEFAULT_ENCODING;
|
||||||
|
|
||||||
|
private String encodingPropertyName;
|
||||||
|
|
||||||
|
private String typeIdPropertyName;
|
||||||
|
|
||||||
|
private Map<String, Class<?>> idClassMappings = new HashMap<String, Class<?>>();
|
||||||
|
|
||||||
|
private Map<Class<?>, String> classIdMappings = new HashMap<Class<?>, String>();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the {@link ObjectMapper} to use instead of using the default.
|
||||||
|
*/
|
||||||
|
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||||
|
Assert.notNull(objectMapper, "ObjectMapper must not be null");
|
||||||
|
this.objectMapper = objectMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify whether {@link #toMessage(Object, Session)} should marshal to a
|
||||||
|
* {@link BytesMessage} or a {@link TextMessage}.
|
||||||
|
* <p>The default is {@link MessageType#BYTES}, i.e. this converter marshals to
|
||||||
|
* a {@link BytesMessage}. Note that the default version of this converter
|
||||||
|
* supports {@link MessageType#BYTES} and {@link MessageType#TEXT} only.
|
||||||
|
* @see MessageType#BYTES
|
||||||
|
* @see MessageType#TEXT
|
||||||
|
*/
|
||||||
|
public void setTargetType(MessageType targetType) {
|
||||||
|
Assert.notNull(targetType, "MessageType must not be null");
|
||||||
|
this.targetType = targetType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the encoding to use when converting to and from text-based
|
||||||
|
* message body content. The default encoding will be "UTF-8".
|
||||||
|
* <p>When reading from a a text-based message, an encoding may have been
|
||||||
|
* suggested through a special JMS property which will then be preferred
|
||||||
|
* over the encoding set on this MessageConverter instance.
|
||||||
|
* @see #setEncodingPropertyName
|
||||||
|
*/
|
||||||
|
public void setEncoding(String encoding) {
|
||||||
|
this.encoding = encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the name of the JMS message property that carries the encoding from
|
||||||
|
* bytes to String and back is BytesMessage is used during the conversion process.
|
||||||
|
* <p>Default is none. Setting this property is optional; if not set, UTF-8 will
|
||||||
|
* be used for decoding any incoming bytes message.
|
||||||
|
* @see #setEncoding
|
||||||
|
*/
|
||||||
|
public void setEncodingPropertyName(String encodingPropertyName) {
|
||||||
|
this.encodingPropertyName = encodingPropertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the name of the JMS message property that carries the type id for the
|
||||||
|
* contained object: either a mapped id value or a raw Java class name.
|
||||||
|
* <p>Default is none. <b>NOTE: This property needs to be set in order to allow
|
||||||
|
* for converting from an incoming message to a Java object.</b>
|
||||||
|
* @see #setTypeIdMappings
|
||||||
|
*/
|
||||||
|
public void setTypeIdPropertyName(String typeIdPropertyName) {
|
||||||
|
this.typeIdPropertyName = typeIdPropertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify mappings from type ids to Java classes, if desired.
|
||||||
|
* This allows for synthetic ids in the type id message property,
|
||||||
|
* instead of transferring Java class names.
|
||||||
|
* <p>Default is no custom mappings, i.e. transferring raw Java class names.
|
||||||
|
* @param typeIdMappings a Map with type id values as keys and Java classes as values
|
||||||
|
*/
|
||||||
|
public void setTypeIdMappings(Map<String, Class<?>> typeIdMappings) {
|
||||||
|
this.idClassMappings = new HashMap<String, Class<?>>();
|
||||||
|
for (Map.Entry<String, Class<?>> entry : typeIdMappings.entrySet()) {
|
||||||
|
String id = entry.getKey();
|
||||||
|
Class<?> clazz = entry.getValue();
|
||||||
|
this.idClassMappings.put(id, clazz);
|
||||||
|
this.classIdMappings.put(clazz, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
|
||||||
|
Message message;
|
||||||
|
try {
|
||||||
|
switch (this.targetType) {
|
||||||
|
case TEXT:
|
||||||
|
message = mapToTextMessage(object, session, this.objectMapper);
|
||||||
|
break;
|
||||||
|
case BYTES:
|
||||||
|
message = mapToBytesMessage(object, session, this.objectMapper);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
message = mapToMessage(object, session, this.objectMapper, this.targetType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new MessageConversionException("Could not map JSON object [" + object + "]", ex);
|
||||||
|
}
|
||||||
|
setTypeIdOnMessage(object, message);
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object fromMessage(Message message) throws JMSException, MessageConversionException {
|
||||||
|
try {
|
||||||
|
JavaType targetJavaType = getJavaTypeForMessage(message);
|
||||||
|
return convertToObject(message, targetJavaType);
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new MessageConversionException("Failed to convert JSON message content", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the given object to a {@link TextMessage}.
|
||||||
|
* @param object the object to be mapped
|
||||||
|
* @param session current JMS session
|
||||||
|
* @param objectMapper the mapper to use
|
||||||
|
* @return the resulting message
|
||||||
|
* @throws JMSException if thrown by JMS methods
|
||||||
|
* @throws IOException in case of I/O errors
|
||||||
|
* @see Session#createBytesMessage
|
||||||
|
* @see Marshaller#marshal(Object, Result)
|
||||||
|
*/
|
||||||
|
protected TextMessage mapToTextMessage(Object object, Session session, ObjectMapper objectMapper)
|
||||||
|
throws JMSException, IOException {
|
||||||
|
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
objectMapper.writeValue(writer, object);
|
||||||
|
return session.createTextMessage(writer.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the given object to a {@link BytesMessage}.
|
||||||
|
* @param object the object to be mapped
|
||||||
|
* @param session current JMS session
|
||||||
|
* @param objectMapper the mapper to use
|
||||||
|
* @return the resulting message
|
||||||
|
* @throws JMSException if thrown by JMS methods
|
||||||
|
* @throws IOException in case of I/O errors
|
||||||
|
* @see Session#createBytesMessage
|
||||||
|
* @see Marshaller#marshal(Object, Result)
|
||||||
|
*/
|
||||||
|
protected BytesMessage mapToBytesMessage(Object object, Session session, ObjectMapper objectMapper)
|
||||||
|
throws JMSException, IOException {
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
OutputStreamWriter writer = new OutputStreamWriter(bos, this.encoding);
|
||||||
|
objectMapper.writeValue(writer, object);
|
||||||
|
|
||||||
|
BytesMessage message = session.createBytesMessage();
|
||||||
|
message.writeBytes(bos.toByteArray());
|
||||||
|
if (this.encodingPropertyName != null) {
|
||||||
|
message.setStringProperty(this.encodingPropertyName, this.encoding);
|
||||||
|
}
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template method that allows for custom message mapping.
|
||||||
|
* Invoked when {@link #setTargetType} is not {@link MessageType#TEXT} or
|
||||||
|
* {@link MessageType#BYTES}.
|
||||||
|
* <p>The default implementation throws an {@link IllegalArgumentException}.
|
||||||
|
* @param object the object to marshal
|
||||||
|
* @param session the JMS Session
|
||||||
|
* @param objectMapper the mapper to use
|
||||||
|
* @param targetType the target message type (other than TEXT or BYTES)
|
||||||
|
* @return the resulting message
|
||||||
|
* @throws JMSException if thrown by JMS methods
|
||||||
|
* @throws IOException in case of I/O errors
|
||||||
|
*/
|
||||||
|
protected Message mapToMessage(Object object, Session session, ObjectMapper objectMapper, MessageType targetType)
|
||||||
|
throws JMSException, IOException {
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Unsupported message type [" + targetType +
|
||||||
|
"]. MappingJacksonMessageConverter by default only supports TextMessages and BytesMessages.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a type id for the given payload object on the given JMS Message.
|
||||||
|
* <p>The default implementation consults the configured type id mapping and
|
||||||
|
* sets the resulting value (either a mapped id or the raw Java class name)
|
||||||
|
* into the configured type id message property.
|
||||||
|
* @param object the payload object to set a type id for
|
||||||
|
* @param message the JMS Message to set the type id on
|
||||||
|
* @throws JMSException if thrown by JMS methods
|
||||||
|
* @see #getJavaTypeForMessage(javax.jms.Message)
|
||||||
|
* @see #setTypeIdPropertyName(String)
|
||||||
|
* @see #setTypeIdMappings(java.util.Map)
|
||||||
|
*/
|
||||||
|
protected void setTypeIdOnMessage(Object object, Message message) throws JMSException {
|
||||||
|
if (this.typeIdPropertyName != null) {
|
||||||
|
String typeId = this.classIdMappings.get(object.getClass());
|
||||||
|
if (typeId == null) {
|
||||||
|
typeId = object.getClass().getName();
|
||||||
|
}
|
||||||
|
message.setStringProperty(this.typeIdPropertyName, typeId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method to dispatch to converters for individual message types.
|
||||||
|
*/
|
||||||
|
private Object convertToObject(Message message, JavaType targetJavaType) throws JMSException, IOException {
|
||||||
|
if (message instanceof TextMessage) {
|
||||||
|
return convertFromTextMessage((TextMessage) message, targetJavaType);
|
||||||
|
}
|
||||||
|
else if (message instanceof BytesMessage) {
|
||||||
|
return convertFromBytesMessage((BytesMessage) message, targetJavaType);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return convertFromMessage(message, targetJavaType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a TextMessage to a Java Object with the specified type.
|
||||||
|
* @param message the input message
|
||||||
|
* @param targetJavaType the target type
|
||||||
|
* @return the message converted to an object
|
||||||
|
* @throws JMSException if thrown by JMS
|
||||||
|
* @throws IOException in case of I/O errors
|
||||||
|
*/
|
||||||
|
protected Object convertFromTextMessage(TextMessage message, JavaType targetJavaType)
|
||||||
|
throws JMSException, IOException {
|
||||||
|
|
||||||
|
String body = message.getText();
|
||||||
|
return this.objectMapper.readValue(body, targetJavaType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a BytesMessage to a Java Object with the specified type.
|
||||||
|
* @param message the input message
|
||||||
|
* @param targetJavaType the target type
|
||||||
|
* @return the message converted to an object
|
||||||
|
* @throws JMSException if thrown by JMS
|
||||||
|
* @throws IOException in case of I/O errors
|
||||||
|
*/
|
||||||
|
protected Object convertFromBytesMessage(BytesMessage message, JavaType targetJavaType)
|
||||||
|
throws JMSException, IOException {
|
||||||
|
|
||||||
|
String encoding = this.encoding;
|
||||||
|
if (this.encodingPropertyName != null && message.propertyExists(this.encodingPropertyName)) {
|
||||||
|
encoding = message.getStringProperty(this.encodingPropertyName);
|
||||||
|
}
|
||||||
|
byte[] bytes = new byte[(int) message.getBodyLength()];
|
||||||
|
message.readBytes(bytes);
|
||||||
|
try {
|
||||||
|
String body = new String(bytes, encoding);
|
||||||
|
return this.objectMapper.readValue(body, targetJavaType);
|
||||||
|
}
|
||||||
|
catch (UnsupportedEncodingException ex) {
|
||||||
|
throw new MessageConversionException("Cannot convert bytes to String", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template method that allows for custom message mapping.
|
||||||
|
* Invoked when {@link #setTargetType} is not {@link MessageType#TEXT} or
|
||||||
|
* {@link MessageType#BYTES}.
|
||||||
|
* <p>The default implementation throws an {@link IllegalArgumentException}.
|
||||||
|
* @param message the input message
|
||||||
|
* @param targetJavaType the target type
|
||||||
|
* @return the message converted to an object
|
||||||
|
* @throws JMSException if thrown by JMS
|
||||||
|
* @throws IOException in case of I/O errors
|
||||||
|
*/
|
||||||
|
protected Object convertFromMessage(Message message, JavaType targetJavaType)
|
||||||
|
throws JMSException, IOException {
|
||||||
|
|
||||||
|
throw new IllegalArgumentException("Unsupported message type [" + message.getClass() +
|
||||||
|
"]. MappingJacksonMessageConverter by default only supports TextMessages and BytesMessages.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine a Jackson JavaType for the given JMS Message,
|
||||||
|
* typically parsing a type id message property.
|
||||||
|
* <p>The default implementation parses the configured type id property name
|
||||||
|
* and consults the configured type id mapping. This can be overridden with
|
||||||
|
* a different strategy, e.g. doing some heuristics based on message origin.
|
||||||
|
* @param object the payload object to set a type id for
|
||||||
|
* @param message the JMS Message to set the type id on
|
||||||
|
* @throws JMSException if thrown by JMS methods
|
||||||
|
* @see #setTypeIdOnMessage(Object, javax.jms.Message)
|
||||||
|
* @see #setTypeIdPropertyName(String)
|
||||||
|
* @see #setTypeIdMappings(java.util.Map)
|
||||||
|
*/
|
||||||
|
protected JavaType getJavaTypeForMessage(Message message) throws JMSException {
|
||||||
|
String typeId = message.getStringProperty(this.typeIdPropertyName);
|
||||||
|
if (typeId == null) {
|
||||||
|
throw new MessageConversionException("Could not find type id property [" + this.typeIdPropertyName + "]");
|
||||||
|
}
|
||||||
|
Class mappedClass = this.idClassMappings.get(typeId);
|
||||||
|
if (mappedClass != null) {
|
||||||
|
return TypeFactory.type(mappedClass);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return TypeFactory.type(ClassUtils.forName(typeId, getClass().getClassLoader()));
|
||||||
|
}
|
||||||
|
catch (Throwable ex) {
|
||||||
|
throw new MessageConversionException("Failed to resolve type id [" + typeId + "]", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -16,17 +16,9 @@
|
||||||
|
|
||||||
package org.springframework.jms.support.converter;
|
package org.springframework.jms.support.converter;
|
||||||
|
|
||||||
import static org.easymock.EasyMock.createMock;
|
|
||||||
import static org.easymock.EasyMock.expect;
|
|
||||||
import static org.easymock.EasyMock.isA;
|
|
||||||
import static org.easymock.EasyMock.replay;
|
|
||||||
import static org.easymock.EasyMock.verify;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.jms.BytesMessage;
|
import javax.jms.BytesMessage;
|
||||||
import javax.jms.Session;
|
import javax.jms.Session;
|
||||||
import javax.jms.TextMessage;
|
import javax.jms.TextMessage;
|
||||||
|
|
@ -36,20 +28,25 @@ import org.easymock.EasyMock;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Dave Syer
|
* @author Dave Syer
|
||||||
*/
|
*/
|
||||||
public class JsonMessageConverterTests {
|
public class MappingJacksonMessageConverterTests {
|
||||||
|
|
||||||
private JsonMessageConverter converter;
|
private MappingJacksonMessageConverter converter;
|
||||||
|
|
||||||
private Session sessionMock;
|
private Session sessionMock;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
sessionMock = createMock(Session.class);
|
sessionMock = createMock(Session.class);
|
||||||
converter = new JsonMessageConverter();
|
converter = new MappingJacksonMessageConverter();
|
||||||
|
converter.setEncodingPropertyName("__encoding__");
|
||||||
|
converter.setTypeIdPropertyName("__typeid__");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -58,11 +55,8 @@ public class JsonMessageConverterTests {
|
||||||
Object toBeMarshalled = new Object();
|
Object toBeMarshalled = new Object();
|
||||||
|
|
||||||
expect(sessionMock.createBytesMessage()).andReturn(bytesMessageMock);
|
expect(sessionMock.createBytesMessage()).andReturn(bytesMessageMock);
|
||||||
bytesMessageMock.setStringProperty(
|
bytesMessageMock.setStringProperty("__encoding__", "UTF-8");
|
||||||
JsonMessageConverter.DEFAULT_ENCODING_PROPERTY_NAME, "UTF-8");
|
bytesMessageMock.setStringProperty("__typeid__", Object.class.getName());
|
||||||
bytesMessageMock.setStringProperty(
|
|
||||||
DefaultJavaTypeMapper.CLASSID_PROPERTY_NAME,
|
|
||||||
Object.class.getName());
|
|
||||||
bytesMessageMock.writeBytes(isA(byte[].class));
|
bytesMessageMock.writeBytes(isA(byte[].class));
|
||||||
|
|
||||||
replay(sessionMock, bytesMessageMock);
|
replay(sessionMock, bytesMessageMock);
|
||||||
|
|
@ -88,12 +82,10 @@ public class JsonMessageConverterTests {
|
||||||
};
|
};
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
bytesMessageMock
|
bytesMessageMock.getStringProperty("__typeid__"))
|
||||||
.getStringProperty(DefaultJavaTypeMapper.CLASSID_PROPERTY_NAME))
|
|
||||||
.andReturn(Object.class.getName());
|
.andReturn(Object.class.getName());
|
||||||
expect(
|
expect(
|
||||||
bytesMessageMock
|
bytesMessageMock.propertyExists("__encoding__"))
|
||||||
.propertyExists(JsonMessageConverter.DEFAULT_ENCODING_PROPERTY_NAME))
|
|
||||||
.andReturn(false);
|
.andReturn(false);
|
||||||
expect(bytesMessageMock.getBodyLength()).andReturn(
|
expect(bytesMessageMock.getBodyLength()).andReturn(
|
||||||
new Long(bytes.length));
|
new Long(bytes.length));
|
||||||
|
|
@ -114,11 +106,8 @@ public class JsonMessageConverterTests {
|
||||||
TextMessage textMessageMock = createMock(TextMessage.class);
|
TextMessage textMessageMock = createMock(TextMessage.class);
|
||||||
Object toBeMarshalled = new Object();
|
Object toBeMarshalled = new Object();
|
||||||
|
|
||||||
textMessageMock.setStringProperty(
|
textMessageMock.setStringProperty("__typeid__", Object.class.getName());
|
||||||
DefaultJavaTypeMapper.CLASSID_PROPERTY_NAME,
|
expect(sessionMock.createTextMessage(isA(String.class))).andReturn( textMessageMock);
|
||||||
Object.class.getName());
|
|
||||||
expect(sessionMock.createTextMessage(isA(String.class))).andReturn(
|
|
||||||
textMessageMock);
|
|
||||||
|
|
||||||
replay(sessionMock, textMessageMock);
|
replay(sessionMock, textMessageMock);
|
||||||
|
|
||||||
|
|
@ -134,15 +123,7 @@ public class JsonMessageConverterTests {
|
||||||
Map<String, String> toBeMarshalled = new HashMap<String, String>();
|
Map<String, String> toBeMarshalled = new HashMap<String, String>();
|
||||||
toBeMarshalled.put("foo", "bar");
|
toBeMarshalled.put("foo", "bar");
|
||||||
|
|
||||||
textMessageMock.setStringProperty(
|
textMessageMock.setStringProperty("__typeid__", HashMap.class.getName());
|
||||||
DefaultJavaTypeMapper.CLASSID_PROPERTY_NAME,
|
|
||||||
HashMap.class.getName());
|
|
||||||
textMessageMock.setStringProperty(
|
|
||||||
DefaultJavaTypeMapper.CONTENT_CLASSID_PROPERTY_NAME,
|
|
||||||
Object.class.getName());
|
|
||||||
textMessageMock.setStringProperty(
|
|
||||||
DefaultJavaTypeMapper.KEY_CLASSID_PROPERTY_NAME,
|
|
||||||
Object.class.getName());
|
|
||||||
expect(sessionMock.createTextMessage(isA(String.class))).andReturn(
|
expect(sessionMock.createTextMessage(isA(String.class))).andReturn(
|
||||||
textMessageMock);
|
textMessageMock);
|
||||||
|
|
||||||
|
|
@ -161,8 +142,7 @@ public class JsonMessageConverterTests {
|
||||||
|
|
||||||
String text = "{\"foo\":\"bar\"}";
|
String text = "{\"foo\":\"bar\"}";
|
||||||
expect(
|
expect(
|
||||||
textMessageMock
|
textMessageMock.getStringProperty("__typeid__"))
|
||||||
.getStringProperty(DefaultJavaTypeMapper.CLASSID_PROPERTY_NAME))
|
|
||||||
.andReturn(Object.class.getName());
|
.andReturn(Object.class.getName());
|
||||||
expect(textMessageMock.getText()).andReturn(text);
|
expect(textMessageMock.getText()).andReturn(text);
|
||||||
|
|
||||||
|
|
@ -182,17 +162,8 @@ public class JsonMessageConverterTests {
|
||||||
|
|
||||||
String text = "{\"foo\":\"bar\"}";
|
String text = "{\"foo\":\"bar\"}";
|
||||||
expect(
|
expect(
|
||||||
textMessageMock
|
textMessageMock.getStringProperty("__typeid__"))
|
||||||
.getStringProperty(DefaultJavaTypeMapper.CLASSID_PROPERTY_NAME))
|
|
||||||
.andReturn(HashMap.class.getName());
|
.andReturn(HashMap.class.getName());
|
||||||
expect(
|
|
||||||
textMessageMock
|
|
||||||
.getStringProperty(DefaultJavaTypeMapper.CONTENT_CLASSID_PROPERTY_NAME))
|
|
||||||
.andReturn(Object.class.getName());
|
|
||||||
expect(
|
|
||||||
textMessageMock
|
|
||||||
.getStringProperty(DefaultJavaTypeMapper.KEY_CLASSID_PROPERTY_NAME))
|
|
||||||
.andReturn(Object.class.getName());
|
|
||||||
expect(textMessageMock.getText()).andReturn(text);
|
expect(textMessageMock.getText()).andReturn(text);
|
||||||
|
|
||||||
replay(sessionMock, textMessageMock);
|
replay(sessionMock, textMessageMock);
|
||||||
Loading…
Reference in New Issue