Use Jackson improved default configuration everywhere

With this commit, Jackson builder is now used in spring-websocket
to create the ObjectMapper instance.

It is not possible to use the builder for spring-messaging
and spring-jms since these modules don't have a dependency on
spring-web, thus they now just customize the same features:
 - MapperFeature#DEFAULT_VIEW_INCLUSION is disabled
 - DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES is disabled

Issue: SPR-12293
This commit is contained in:
Sebastien Deleuze
2014-12-03 09:49:41 +01:00
parent 87f1512e88
commit fbd85925de
9 changed files with 146 additions and 17 deletions

View File

@@ -29,7 +29,9 @@ import javax.jms.Message;
import javax.jms.Session;
import javax.jms.TextMessage;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.BeanClassLoaderAware;
@@ -42,6 +44,12 @@ import org.springframework.util.ClassUtils;
* {@link #setTargetType targetType} is set to {@link MessageType#TEXT}.
* Converts from a {@link TextMessage} or {@link BytesMessage} to an object.
*
* <p>It customizes Jackson's default properties with the following ones:
* <ul>
* <li>{@link MapperFeature#DEFAULT_VIEW_INCLUSION} is disabled</li>
* <li>{@link DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES} is disabled</li>
* </ul>
*
* <p>Tested against Jackson 2.2; compatible with Jackson 2.0 and higher.
*
* @author Mark Pollack
@@ -57,7 +65,7 @@ public class MappingJackson2MessageConverter implements MessageConverter, BeanCl
public static final String DEFAULT_ENCODING = "UTF-8";
private ObjectMapper objectMapper = new ObjectMapper();
private ObjectMapper objectMapper;
private MessageType targetType = MessageType.BYTES;
@@ -74,6 +82,12 @@ public class MappingJackson2MessageConverter implements MessageConverter, BeanCl
private ClassLoader beanClassLoader;
public MappingJackson2MessageConverter() {
this.objectMapper = new ObjectMapper();
this.objectMapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
/**
* Specify the {@link ObjectMapper} to use instead of using the default.
*/

View File

@@ -115,6 +115,32 @@ public class MappingJackson2MessageConverterTests {
verify(textMessageMock).setStringProperty("__typeid__", HashMap.class.getName());
}
@Test
public void fromTextMessage() throws Exception {
TextMessage textMessageMock = mock(TextMessage.class);
MyBean unmarshalled = new MyBean("bar");
String text = "{\"foo\":\"bar\"}";
given(textMessageMock.getStringProperty("__typeid__")).willReturn(MyBean.class.getName());
given(textMessageMock.getText()).willReturn(text);
MyBean result = (MyBean)converter.fromMessage(textMessageMock);
assertEquals("Invalid result", result, unmarshalled);
}
@Test
public void fromTextMessageWithUnknownProperty() throws Exception {
TextMessage textMessageMock = mock(TextMessage.class);
MyBean unmarshalled = new MyBean("bar");
String text = "{\"foo\":\"bar\", \"unknownProperty\":\"value\"}";
given(textMessageMock.getStringProperty("__typeid__")).willReturn(MyBean.class.getName());
given(textMessageMock.getText()).willReturn(text);
MyBean result = (MyBean)converter.fromMessage(textMessageMock);
assertEquals("Invalid result", result, unmarshalled);
}
@Test
public void fromTextMessageAsObject() throws Exception {
TextMessage textMessageMock = mock(TextMessage.class);
@@ -141,4 +167,47 @@ public class MappingJackson2MessageConverterTests {
assertEquals("Invalid result", result, unmarshalled);
}
public static class MyBean {
public MyBean() {
}
public MyBean(String foo) {
this.foo = foo;
}
private String foo;
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MyBean bean = (MyBean) o;
if (foo != null ? !foo.equals(bean.foo) : bean.foo != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
return foo != null ? foo.hashCode() : 0;
}
}
}