Added MappingJackson2MessageConverter for JMS
Issue: SPR-10099
This commit is contained in:
@@ -335,10 +335,11 @@ project("spring-jms") {
|
||||
compile(project(":spring-tx"))
|
||||
optional(project(":spring-oxm"))
|
||||
compile("aopalliance:aopalliance:1.0")
|
||||
optional("org.codehaus.jackson:jackson-mapper-asl:1.4.2")
|
||||
provided("org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1")
|
||||
optional("org.apache.geronimo.specs:geronimo-jta_1.1_spec:1.1")
|
||||
optional("javax.resource:connector-api:1.5")
|
||||
optional("org.codehaus.jackson:jackson-mapper-asl:1.4.2")
|
||||
optional("com.fasterxml.jackson.core:jackson-databind:2.0.1")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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 com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Message converter that uses the Jackson 2 library to convert messages to and from JSON.
|
||||
* Maps an object to a {@link javax.jms.BytesMessage}, or to a {@link javax.jms.TextMessage} if the
|
||||
* {@link #setTargetType targetType} is set to {@link org.springframework.jms.support.converter.MessageType#TEXT}.
|
||||
* Converts from a {@link javax.jms.TextMessage} or {@link javax.jms.BytesMessage} to an object.
|
||||
*
|
||||
* @author Mark Pollack
|
||||
* @author Dave Syer
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1.4
|
||||
*/
|
||||
public class MappingJackson2MessageConverter 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 org.codehaus.jackson.map.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, javax.jms.Session)} should marshal to a
|
||||
* {@link javax.jms.BytesMessage} or a {@link javax.jms.TextMessage}.
|
||||
* <p>The default is {@link org.springframework.jms.support.converter.MessageType#BYTES}, i.e. this converter marshals to
|
||||
* a {@link javax.jms.BytesMessage}. Note that the default version of this converter
|
||||
* supports {@link org.springframework.jms.support.converter.MessageType#BYTES} and {@link org.springframework.jms.support.converter.MessageType#TEXT} only.
|
||||
* @see org.springframework.jms.support.converter.MessageType#BYTES
|
||||
* @see org.springframework.jms.support.converter.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 javax.jms.TextMessage}.
|
||||
* @param object the object to be mapped
|
||||
* @param session current JMS session
|
||||
* @param objectMapper the mapper to use
|
||||
* @return the resulting message
|
||||
* @throws javax.jms.JMSException if thrown by JMS methods
|
||||
* @throws java.io.IOException in case of I/O errors
|
||||
* @see javax.jms.Session#createBytesMessage
|
||||
* @see org.springframework.oxm.Marshaller#marshal(Object, javax.xml.transform.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 javax.jms.BytesMessage}.
|
||||
* @param object the object to be mapped
|
||||
* @param session current JMS session
|
||||
* @param objectMapper the mapper to use
|
||||
* @return the resulting message
|
||||
* @throws javax.jms.JMSException if thrown by JMS methods
|
||||
* @throws java.io.IOException in case of I/O errors
|
||||
* @see javax.jms.Session#createBytesMessage
|
||||
* @see org.springframework.oxm.Marshaller#marshal(Object, javax.xml.transform.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 org.springframework.jms.support.converter.MessageType#TEXT} or
|
||||
* {@link org.springframework.jms.support.converter.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 javax.jms.JMSException if thrown by JMS methods
|
||||
* @throws java.io.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 javax.jms.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 javax.jms.JMSException if thrown by JMS
|
||||
* @throws java.io.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 javax.jms.JMSException if thrown by JMS
|
||||
* @throws java.io.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 org.springframework.jms.support.converter.MessageType#TEXT} or
|
||||
* {@link org.springframework.jms.support.converter.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 javax.jms.JMSException if thrown by JMS
|
||||
* @throws java.io.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 message the JMS Message to set the type id on
|
||||
* @throws javax.jms.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 this.objectMapper.getTypeFactory().constructType(mappedClass);
|
||||
}
|
||||
try {
|
||||
return this.objectMapper.getTypeFactory().constructType(
|
||||
ClassUtils.forName(typeId, getClass().getClassLoader()));
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new MessageConversionException("Failed to resolve type id [" + typeId + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.jms.BytesMessage;
|
||||
import javax.jms.Session;
|
||||
import javax.jms.TextMessage;
|
||||
|
||||
import org.easymock.Capture;
|
||||
import org.easymock.EasyMock;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.easymock.EasyMock.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class MappingJackson2MessageConverterTests {
|
||||
|
||||
private MappingJackson2MessageConverter converter;
|
||||
|
||||
private Session sessionMock;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
sessionMock = createMock(Session.class);
|
||||
converter = new MappingJackson2MessageConverter();
|
||||
converter.setEncodingPropertyName("__encoding__");
|
||||
converter.setTypeIdPropertyName("__typeid__");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toBytesMessage() throws Exception {
|
||||
BytesMessage bytesMessageMock = createMock(BytesMessage.class);
|
||||
Date toBeMarshalled = new Date();
|
||||
|
||||
expect(sessionMock.createBytesMessage()).andReturn(bytesMessageMock);
|
||||
bytesMessageMock.setStringProperty("__encoding__", "UTF-8");
|
||||
bytesMessageMock.setStringProperty("__typeid__", Date.class.getName());
|
||||
bytesMessageMock.writeBytes(isA(byte[].class));
|
||||
|
||||
replay(sessionMock, bytesMessageMock);
|
||||
|
||||
converter.toMessage(toBeMarshalled, sessionMock);
|
||||
|
||||
verify(sessionMock, bytesMessageMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromBytesMessage() throws Exception {
|
||||
BytesMessage bytesMessageMock = createMock(BytesMessage.class);
|
||||
Map<String, String> unmarshalled = Collections.singletonMap("foo",
|
||||
"bar");
|
||||
|
||||
final byte[] bytes = "{\"foo\":\"bar\"}".getBytes();
|
||||
Capture<byte[]> captured = new Capture<byte[]>() {
|
||||
@Override
|
||||
public void setValue(byte[] value) {
|
||||
super.setValue(value);
|
||||
System.arraycopy(bytes, 0, value, 0, bytes.length);
|
||||
}
|
||||
};
|
||||
|
||||
expect(
|
||||
bytesMessageMock.getStringProperty("__typeid__"))
|
||||
.andReturn(Object.class.getName());
|
||||
expect(
|
||||
bytesMessageMock.propertyExists("__encoding__"))
|
||||
.andReturn(false);
|
||||
expect(bytesMessageMock.getBodyLength()).andReturn(
|
||||
new Long(bytes.length));
|
||||
expect(bytesMessageMock.readBytes(EasyMock.capture(captured)))
|
||||
.andReturn(bytes.length);
|
||||
|
||||
replay(sessionMock, bytesMessageMock);
|
||||
|
||||
Object result = converter.fromMessage(bytesMessageMock);
|
||||
assertEquals("Invalid result", result, unmarshalled);
|
||||
|
||||
verify(sessionMock, bytesMessageMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toTextMessageWithObject() throws Exception {
|
||||
converter.setTargetType(MessageType.TEXT);
|
||||
TextMessage textMessageMock = createMock(TextMessage.class);
|
||||
Date toBeMarshalled = new Date();
|
||||
|
||||
textMessageMock.setStringProperty("__typeid__", Date.class.getName());
|
||||
expect(sessionMock.createTextMessage(isA(String.class))).andReturn( textMessageMock);
|
||||
|
||||
replay(sessionMock, textMessageMock);
|
||||
|
||||
converter.toMessage(toBeMarshalled, sessionMock);
|
||||
|
||||
verify(sessionMock, textMessageMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toTextMessageWithMap() throws Exception {
|
||||
converter.setTargetType(MessageType.TEXT);
|
||||
TextMessage textMessageMock = createMock(TextMessage.class);
|
||||
Map<String, String> toBeMarshalled = new HashMap<String, String>();
|
||||
toBeMarshalled.put("foo", "bar");
|
||||
|
||||
textMessageMock.setStringProperty("__typeid__", HashMap.class.getName());
|
||||
expect(sessionMock.createTextMessage(isA(String.class))).andReturn(
|
||||
textMessageMock);
|
||||
|
||||
replay(sessionMock, textMessageMock);
|
||||
|
||||
converter.toMessage(toBeMarshalled, sessionMock);
|
||||
|
||||
verify(sessionMock, textMessageMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromTextMessageAsObject() throws Exception {
|
||||
TextMessage textMessageMock = createMock(TextMessage.class);
|
||||
Map<String, String> unmarshalled = Collections.singletonMap("foo",
|
||||
"bar");
|
||||
|
||||
String text = "{\"foo\":\"bar\"}";
|
||||
expect(
|
||||
textMessageMock.getStringProperty("__typeid__"))
|
||||
.andReturn(Object.class.getName());
|
||||
expect(textMessageMock.getText()).andReturn(text);
|
||||
|
||||
replay(sessionMock, textMessageMock);
|
||||
|
||||
Object result = converter.fromMessage(textMessageMock);
|
||||
assertEquals("Invalid result", result, unmarshalled);
|
||||
|
||||
verify(sessionMock, textMessageMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromTextMessageAsMap() throws Exception {
|
||||
TextMessage textMessageMock = createMock(TextMessage.class);
|
||||
Map<String, String> unmarshalled = Collections.singletonMap("foo",
|
||||
"bar");
|
||||
|
||||
String text = "{\"foo\":\"bar\"}";
|
||||
expect(
|
||||
textMessageMock.getStringProperty("__typeid__"))
|
||||
.andReturn(HashMap.class.getName());
|
||||
expect(textMessageMock.getText()).andReturn(text);
|
||||
|
||||
replay(sessionMock, textMessageMock);
|
||||
|
||||
Object result = converter.fromMessage(textMessageMock);
|
||||
assertEquals("Invalid result", result, unmarshalled);
|
||||
|
||||
verify(sessionMock, textMessageMock);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,11 +49,12 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Keith Donald
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1.2
|
||||
* @see org.springframework.web.servlet.view.json.MappingJackson2JsonView
|
||||
*/
|
||||
public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConverter<Object>
|
||||
implements GenericHttpMessageConverter<Object> {
|
||||
implements GenericHttpMessageConverter<Object> {
|
||||
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
|
||||
import org.codehaus.jackson.JsonEncoding;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
@@ -53,7 +52,7 @@ import org.springframework.util.Assert;
|
||||
* @see org.springframework.web.servlet.view.json.MappingJacksonJsonView
|
||||
*/
|
||||
public class MappingJacksonHttpMessageConverter extends AbstractHttpMessageConverter<Object>
|
||||
implements GenericHttpMessageConverter<Object> {
|
||||
implements GenericHttpMessageConverter<Object> {
|
||||
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
@@ -112,7 +111,7 @@ public class MappingJacksonHttpMessageConverter extends AbstractHttpMessageConve
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to use the {@link DefaultPrettyPrinter} when writing JSON.
|
||||
* Whether to use the {@link org.codehaus.jackson.impl.DefaultPrettyPrinter} when writing JSON.
|
||||
* This is a shortcut for setting up an {@code ObjectMapper} as follows:
|
||||
* <pre>
|
||||
* ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
Reference in New Issue
Block a user