提交 3a4e5d5d 编写于 作者: S Sebastien Deleuze

Fix ParameterizedType + contextClass support in Jackson converter

Issue: SPR-14470
上级 b52b56c9
......@@ -17,6 +17,7 @@
package org.springframework.http.converter.json;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.nio.charset.Charset;
......@@ -312,11 +313,37 @@ public abstract class AbstractJackson2HttpMessageConverter extends AbstractGener
*/
protected JavaType getJavaType(Type type, Class<?> contextClass) {
TypeFactory typeFactory = this.objectMapper.getTypeFactory();
if (type instanceof TypeVariable && contextClass != null) {
ResolvableType resolvedType = resolveVariable(
(TypeVariable<?>) type, ResolvableType.forClass(contextClass));
if (resolvedType != ResolvableType.NONE) {
return typeFactory.constructType(resolvedType.resolve());
if (contextClass != null) {
ResolvableType resolvedType = ResolvableType.forType(type);
if (type instanceof TypeVariable) {
ResolvableType resolvedTypeVariable = resolveVariable(
(TypeVariable<?>) type, ResolvableType.forClass(contextClass));
if (resolvedTypeVariable != ResolvableType.NONE) {
return typeFactory.constructType(resolvedTypeVariable.resolve());
}
}
else if (type instanceof ParameterizedType && resolvedType.hasUnresolvableGenerics()) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Class<?>[] generics = new Class<?>[parameterizedType.getActualTypeArguments().length];
Type[] typeArguments = parameterizedType.getActualTypeArguments();
for (int i = 0; i < typeArguments.length; i++) {
Type typeArgument = typeArguments[i];
if (typeArgument instanceof TypeVariable) {
ResolvableType resolvedTypeArgument = resolveVariable(
(TypeVariable<?>) typeArgument, ResolvableType.forClass(contextClass));
if (resolvedTypeArgument != ResolvableType.NONE) {
generics[i] = resolvedTypeArgument.resolve();
}
else {
generics[i] = ResolvableType.forType(typeArgument).resolve();
}
}
else {
generics[i] = ResolvableType.forType(typeArgument).resolve();
}
}
return typeFactory.constructType(ResolvableType.
forClassWithGenerics(resolvedType.getRawClass(), generics).getType());
}
}
return typeFactory.constructType(type);
......
......@@ -240,6 +240,29 @@ public class RequestResponseBodyMethodProcessorTests {
assertEquals("Jad", result.getName());
}
@Test // SPR-14470
public void resolveParameterizedWithTypeVariableArgument() throws Exception {
Method method = MyParameterizedControllerWithList.class.getMethod("handleDto", List.class);
HandlerMethod handlerMethod = new HandlerMethod(new MySimpleParameterizedControllerWithList(), method);
MethodParameter methodParam = handlerMethod.getMethodParameters()[0];
String content = "[{\"name\" : \"Jad\"}, {\"name\" : \"Robert\"}]";
this.servletRequest.setContent(content.getBytes("UTF-8"));
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
List<HttpMessageConverter<?>> converters = new ArrayList<>();
converters.add(new MappingJackson2HttpMessageConverter());
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
@SuppressWarnings("unchecked")
List<SimpleBean> result = (List<SimpleBean>)
processor.resolveArgument(methodParam, container, request, factory);
assertNotNull(result);
assertEquals("Jad", result.get(0).getName());
assertEquals("Robert", result.get(1).getName());
}
@Test // SPR-11225
public void resolveArgumentTypeVariableWithNonGenericConverter() throws Exception {
Method method = MyParameterizedController.class.getMethod("handleDto", Identifiable.class);
......@@ -725,6 +748,17 @@ public class RequestResponseBodyMethodProcessorTests {
void setId(Long id);
}
@SuppressWarnings("unused")
private static abstract class MyParameterizedControllerWithList<DTO extends Identifiable> {
public void handleDto(@RequestBody List<DTO> dto) {
}
}
@SuppressWarnings("unused")
private static class MySimpleParameterizedControllerWithList extends MyParameterizedControllerWithList<SimpleBean> {
}
@SuppressWarnings({ "serial" })
private static class SimpleBean implements Identifiable {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册