Skip to content

Commit 583201b

Browse files
committed
MappingJackson2MessageConverter uses generic type
Issue: SPR-16252
1 parent f051755 commit 583201b

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@
3737
import com.fasterxml.jackson.databind.ObjectMapper;
3838
import com.fasterxml.jackson.databind.SerializationFeature;
3939

40+
import org.springframework.core.GenericTypeResolver;
4041
import org.springframework.core.MethodParameter;
42+
import org.springframework.core.ResolvableType;
4143
import org.springframework.lang.Nullable;
4244
import org.springframework.messaging.Message;
4345
import org.springframework.messaging.MessageHeaders;
@@ -207,7 +209,7 @@ protected boolean supports(Class<?> clazz) {
207209
@Override
208210
@Nullable
209211
protected Object convertFromInternal(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
210-
JavaType javaType = this.objectMapper.constructType(targetClass);
212+
JavaType javaType = getJavaType(targetClass, conversionHint);
211213
Object payload = message.getPayload();
212214
Class<?> view = getSerializationView(conversionHint);
213215
// Note: in the view case, calling withType instead of forType for compatibility with Jackson <2.5
@@ -234,6 +236,18 @@ protected Object convertFromInternal(Message<?> message, Class<?> targetClass, @
234236
}
235237
}
236238

239+
private JavaType getJavaType(Class<?> targetClass, @Nullable Object conversionHint) {
240+
if (conversionHint instanceof MethodParameter) {
241+
MethodParameter param = (MethodParameter) conversionHint;
242+
param = param.nestedIfOptional();
243+
Type genericParameterType = param.getNestedGenericParameterType();
244+
Class<?> contextClass = param.getContainingClass();
245+
Type type = GenericTypeResolver.resolveType(genericParameterType, contextClass);
246+
return this.objectMapper.getTypeFactory().constructType(type);
247+
}
248+
return this.objectMapper.constructType(targetClass);
249+
}
250+
237251
@Override
238252
@Nullable
239253
protected Object convertToInternal(Object payload, @Nullable MessageHeaders headers,

spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.nio.charset.StandardCharsets;
2222
import java.util.Arrays;
2323
import java.util.HashMap;
24+
import java.util.List;
2425
import java.util.Map;
2526

2627
import com.fasterxml.jackson.annotation.JsonView;
@@ -33,8 +34,16 @@
3334
import org.springframework.messaging.support.MessageBuilder;
3435
import org.springframework.util.MimeType;
3536

36-
import static org.hamcrest.Matchers.*;
37-
import static org.junit.Assert.*;
37+
import static org.hamcrest.Matchers.contains;
38+
import static org.hamcrest.Matchers.containsString;
39+
import static org.hamcrest.Matchers.not;
40+
import static org.junit.Assert.assertArrayEquals;
41+
import static org.junit.Assert.assertEquals;
42+
import static org.junit.Assert.assertFalse;
43+
import static org.junit.Assert.assertNotNull;
44+
import static org.junit.Assert.assertNull;
45+
import static org.junit.Assert.assertThat;
46+
import static org.junit.Assert.assertTrue;
3847

3948
/**
4049
* Test fixture for {@link org.springframework.messaging.converter.MappingJackson2MessageConverter}.
@@ -127,6 +136,20 @@ public void fromMessageValidJsonWithUnknownProperty() throws IOException {
127136
assertEquals("string", myBean.getString());
128137
}
129138

139+
@Test // SPR-16252
140+
public void fromMessageToList() throws Exception {
141+
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
142+
String payload = "[1, 2, 3, 4, 5, 6, 7, 8, 9]";
143+
Message<?> message = MessageBuilder.withPayload(payload.getBytes(StandardCharsets.UTF_8)).build();
144+
145+
Method method = getClass().getDeclaredMethod("handleList", List.class);
146+
MethodParameter param = new MethodParameter(method, 0);
147+
Object actual = converter.fromMessage(message, List.class, param);
148+
149+
assertNotNull(actual);
150+
assertEquals(Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L), actual);
151+
}
152+
130153
@Test
131154
public void toMessage() throws Exception {
132155
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
@@ -217,6 +240,8 @@ public JacksonViewBean jsonViewResponse() {
217240
public void jsonViewPayload(@JsonView(MyJacksonView2.class) JacksonViewBean payload) {
218241
}
219242

243+
void handleList(List<Long> payload) {}
244+
220245

221246
public static class MyBean {
222247

0 commit comments

Comments
 (0)