Consistent conversion of Optional array/list arrangements

Issue: SPR-15918
Issue: SPR-15919
Issue: SPR-15676
This commit is contained in:
Juergen Hoeller
2017-09-20 18:28:49 +02:00
parent ea01c4113a
commit 15c82afc1c
5 changed files with 302 additions and 32 deletions

View File

@@ -54,7 +54,7 @@ import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.ValueConstants;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.*;
/**
* Convenience class to resolve method parameters from hints.
@@ -238,9 +238,8 @@ public class ResolvableMethod {
}
private static ResolvableType toResolvableType(Class<?> type, Class<?>... generics) {
return ObjectUtils.isEmpty(generics) ?
ResolvableType.forClass(type) :
ResolvableType.forClassWithGenerics(type, generics);
return (ObjectUtils.isEmpty(generics) ? ResolvableType.forClass(type) :
ResolvableType.forClassWithGenerics(type, generics));
}
private static ResolvableType toResolvableType(Class<?> type, ResolvableType generic, ResolvableType... generics) {

View File

@@ -48,16 +48,9 @@ import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.mock;
import static org.springframework.web.method.MvcAnnotationPredicates.requestParam;
import static org.springframework.web.method.MvcAnnotationPredicates.requestPart;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.web.method.MvcAnnotationPredicates.*;
/**
* Test fixture with {@link org.springframework.web.method.annotation.RequestParamMethodArgumentResolver}.
@@ -76,13 +69,15 @@ public class RequestParamMethodArgumentResolverTests {
private ResolvableMethod testMethod = ResolvableMethod.on(getClass()).named("handle").build();
@Before
public void setUp() throws Exception {
public void setup() throws Exception {
resolver = new RequestParamMethodArgumentResolver(null, true);
request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
}
@Test
public void supportsParameter() {
resolver = new RequestParamMethodArgumentResolver(null, true);
@@ -470,6 +465,88 @@ public class RequestParamMethodArgumentResolverTests {
assertEquals(123, ((Optional) result).get());
}
@Test
@SuppressWarnings("rawtypes")
public void missingOptionalParamValue() throws Exception {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(new DefaultConversionService());
WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer);
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, Integer.class);
Object result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.empty(), result);
result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.class, result.getClass());
assertFalse(((Optional) result).isPresent());
}
@Test
@SuppressWarnings("rawtypes")
public void resolveOptionalParamArray() throws Exception {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(new DefaultConversionService());
WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer);
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, Integer[].class);
Object result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.empty(), result);
this.request.addParameter("name", "123", "456");
result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.class, result.getClass());
assertArrayEquals(new Integer[] {123, 456}, (Integer[]) ((Optional) result).get());
}
@Test
@SuppressWarnings("rawtypes")
public void missingOptionalParamArray() throws Exception {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(new DefaultConversionService());
WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer);
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, Integer[].class);
Object result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.empty(), result);
result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.class, result.getClass());
assertFalse(((Optional) result).isPresent());
}
@Test
@SuppressWarnings("rawtypes")
public void resolveOptionalParamList() throws Exception {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(new DefaultConversionService());
WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer);
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, List.class);
Object result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.empty(), result);
this.request.addParameter("name", "123", "456");
result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.class, result.getClass());
assertEquals(Arrays.asList("123", "456"), ((Optional) result).get());
}
@Test
@SuppressWarnings("rawtypes")
public void missingOptionalParamList() throws Exception {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(new DefaultConversionService());
WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer);
MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, List.class);
Object result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.empty(), result);
result = resolver.resolveArgument(param, null, webRequest, binderFactory);
assertEquals(Optional.class, result.getClass());
assertFalse(((Optional) result).isPresent());
}
@Test
public void resolveOptionalMultipartFile() throws Exception {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
@@ -536,6 +613,8 @@ public class RequestParamMethodArgumentResolverTests {
@RequestParam("name") String paramRequired,
@RequestParam(name = "name", required = false) String paramNotRequired,
@RequestParam("name") Optional<Integer> paramOptional,
@RequestParam("name") Optional<Integer[]> paramOptionalArray,
@RequestParam("name") Optional<List> paramOptionalList,
@RequestParam("mfile") Optional<MultipartFile> multipartFileOptional) {
}