Browse Source

Serialize with type only collections in Jackson HttpMessageConverter

Issue: SPR-13318
pull/861/merge
Sebastien Deleuze 11 years ago
parent
commit
4338719d98
  1. 2
      spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java
  2. 48
      spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java
  3. 66
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java

2
spring-web/src/main/java/org/springframework/http/converter/json/AbstractJackson2HttpMessageConverter.java

@ -258,7 +258,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener @@ -258,7 +258,7 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
else {
objectWriter = this.objectMapper.writer();
}
if (javaType != null) {
if (javaType != null && javaType.isContainerType()) {
objectWriter = objectWriter.withType(javaType);
}
objectWriter.writeValue(generator, value);

48
spring-web/src/test/java/org/springframework/http/converter/json/MappingJackson2HttpMessageConverterTests.java

@ -315,8 +315,54 @@ public class MappingJackson2HttpMessageConverterTests { @@ -315,8 +315,54 @@ public class MappingJackson2HttpMessageConverterTests {
assertThat(result, not(containsString("\"withoutView\":\"without\"")));
}
@Test // SPR-13318
public void writeSubType() throws Exception {
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
MyBean bean = new MyBean();
bean.setString("Foo");
bean.setNumber(42);
this.converter.writeInternal(bean, MyInterface.class, outputMessage);
String result = outputMessage.getBodyAsString(Charset.forName("UTF-8"));
assertTrue(result.contains("\"string\":\"Foo\""));
assertTrue(result.contains("\"number\":42"));
}
@Test // SPR-13318
public void writeSubTypeList() throws Exception {
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
List<MyBean> beans = new ArrayList<MyBean>();
MyBean foo = new MyBean();
foo.setString("Foo");
foo.setNumber(42);
beans.add(foo);
MyBean bar = new MyBean();
bar.setString("Bar");
bar.setNumber(123);
beans.add(bar);
ParameterizedTypeReference<List<MyInterface>> typeReference =
new ParameterizedTypeReference<List<MyInterface>>() {};
this.converter.writeInternal(beans, typeReference.getType(), outputMessage);
String result = outputMessage.getBodyAsString(Charset.forName("UTF-8"));
assertTrue(result.contains("\"string\":\"Foo\""));
assertTrue(result.contains("\"number\":42"));
assertTrue(result.contains("\"string\":\"Bar\""));
assertTrue(result.contains("\"number\":123"));
}
interface MyInterface {
String getString();
void setString(String string);
}
public static class MyBean {
public static class MyBean implements MyInterface {
private String string;

66
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java

@ -24,6 +24,7 @@ import java.io.Serializable; @@ -24,6 +24,7 @@ import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -543,7 +544,7 @@ public class RequestResponseBodyMethodProcessorTests { @@ -543,7 +544,7 @@ public class RequestResponseBodyMethodProcessorTests {
@Test // SPR-12811
public void jacksonTypeInfoList() throws Exception {
Method method = JacksonController.class.getMethod("handleList");
Method method = JacksonController.class.getMethod("handleTypeInfoList");
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
MethodParameter methodReturnType = handlerMethod.getReturnType();
@ -551,7 +552,7 @@ public class RequestResponseBodyMethodProcessorTests { @@ -551,7 +552,7 @@ public class RequestResponseBodyMethodProcessorTests {
converters.add(new MappingJackson2HttpMessageConverter());
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
Object returnValue = new JacksonController().handleList();
Object returnValue = new JacksonController().handleTypeInfoList();
processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest);
String content = this.servletResponse.getContentAsString();
@ -559,6 +560,44 @@ public class RequestResponseBodyMethodProcessorTests { @@ -559,6 +560,44 @@ public class RequestResponseBodyMethodProcessorTests {
assertTrue(content.contains("\"type\":\"bar\""));
}
@Test // SPR-13318
public void jacksonSubType() throws Exception {
Method method = JacksonController.class.getMethod("handleSubType");
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
MethodParameter methodReturnType = handlerMethod.getReturnType();
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new MappingJackson2HttpMessageConverter());
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
Object returnValue = new JacksonController().handleSubType();
processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest);
String content = this.servletResponse.getContentAsString();
assertTrue(content.contains("\"id\":123"));
assertTrue(content.contains("\"name\":\"foo\""));
}
@Test // SPR-13318
public void jacksonSubTypeList() throws Exception {
Method method = JacksonController.class.getMethod("handleSubTypeList");
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
MethodParameter methodReturnType = handlerMethod.getReturnType();
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new MappingJackson2HttpMessageConverter());
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
Object returnValue = new JacksonController().handleSubTypeList();
processor.handleReturnValue(returnValue, methodReturnType, this.mavContainer, this.webRequest);
String content = this.servletResponse.getContentAsString();
assertTrue(content.contains("\"id\":123"));
assertTrue(content.contains("\"name\":\"foo\""));
assertTrue(content.contains("\"id\":456"));
assertTrue(content.contains("\"name\":\"bar\""));
}
String handle(
@RequestBody List<SimpleBean> list,
@ -774,12 +813,33 @@ public class RequestResponseBodyMethodProcessorTests { @@ -774,12 +813,33 @@ public class RequestResponseBodyMethodProcessorTests {
@RequestMapping
@ResponseBody
public List<ParentClass> handleList() {
public List<ParentClass> handleTypeInfoList() {
List<ParentClass> list = new ArrayList<>();
list.add(new Foo("foo"));
list.add(new Bar("bar"));
return list;
}
@RequestMapping
@ResponseBody
public Identifiable handleSubType() {
SimpleBean foo = new SimpleBean();
foo.setId(123L);
foo.setName("foo");
return foo;
}
@RequestMapping
@ResponseBody
public List<Identifiable> handleSubTypeList() {
SimpleBean foo = new SimpleBean();
foo.setId(123L);
foo.setName("foo");
SimpleBean bar = new SimpleBean();
bar.setId(456L);
bar.setName("bar");
return Arrays.asList(foo, bar);
}
}
private static class EmptyRequestBodyAdvice implements RequestBodyAdvice {

Loading…
Cancel
Save