diff --git a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java index 0146adc7801..7d554e9052d 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/support/MultipartResolutionDelegate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -99,37 +99,53 @@ public final class MultipartResolutionDelegate { boolean isMultipart = (multipartRequest != null || isMultipartContent(request)); if (MultipartFile.class == parameter.getNestedParameterType()) { - if (multipartRequest == null && isMultipart) { + if (!isMultipart) { + return null; + } + if (multipartRequest == null) { multipartRequest = new StandardMultipartHttpServletRequest(request); } - return (multipartRequest != null ? multipartRequest.getFile(name) : null); + return multipartRequest.getFile(name); } else if (isMultipartFileCollection(parameter)) { - if (multipartRequest == null && isMultipart) { + if (!isMultipart) { + return null; + } + if (multipartRequest == null) { multipartRequest = new StandardMultipartHttpServletRequest(request); } - return (multipartRequest != null ? multipartRequest.getFiles(name) : null); + List files = multipartRequest.getFiles(name); + return (!files.isEmpty() ? files : null); } else if (isMultipartFileArray(parameter)) { - if (multipartRequest == null && isMultipart) { - multipartRequest = new StandardMultipartHttpServletRequest(request); - } - if (multipartRequest != null) { - List multipartFiles = multipartRequest.getFiles(name); - return multipartFiles.toArray(new MultipartFile[0]); - } - else { + if (!isMultipart) { return null; } + if (multipartRequest == null) { + multipartRequest = new StandardMultipartHttpServletRequest(request); + } + List files = multipartRequest.getFiles(name); + return (!files.isEmpty() ? files.toArray(new MultipartFile[0]) : null); } else if (Part.class == parameter.getNestedParameterType()) { - return (isMultipart ? request.getPart(name): null); + if (!isMultipart) { + return null; + } + return request.getPart(name); } else if (isPartCollection(parameter)) { - return (isMultipart ? resolvePartList(request, name) : null); + if (!isMultipart) { + return null; + } + List parts = resolvePartList(request, name); + return (!parts.isEmpty() ? parts : null); } else if (isPartArray(parameter)) { - return (isMultipart ? resolvePartList(request, name).toArray(new Part[0]) : null); + if (!isMultipart) { + return null; + } + List parts = resolvePartList(request, name); + return (!parts.isEmpty() ? parts.toArray(new Part[0]) : null); } else { return UNRESOLVABLE; diff --git a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java index 6cef633eae0..5ad7e894bb1 100644 --- a/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java +++ b/spring-web/src/test/java/org/springframework/web/method/annotation/RequestParamMethodArgumentResolverTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -199,6 +199,17 @@ public class RequestParamMethodArgumentResolverTests { assertThat(result).isEqualTo(Arrays.asList(expected1, expected2)); } + @Test + public void resolveMultipartFileListMissing() throws Exception { + MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); + request.addFile(new MockMultipartFile("other", "Hello World 3".getBytes())); + webRequest = new ServletWebRequest(request); + + MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(List.class, MultipartFile.class); + assertThatExceptionOfType(MissingServletRequestPartException.class).isThrownBy(() -> + resolver.resolveArgument(param, null, webRequest, null)); + } + @Test public void resolveMultipartFileArray() throws Exception { MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); @@ -220,6 +231,17 @@ public class RequestParamMethodArgumentResolverTests { assertThat(expected2).isEqualTo(parts[1]); } + @Test + public void resolveMultipartFileArrayMissing() throws Exception { + MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(); + request.addFile(new MockMultipartFile("other", "Hello World 3".getBytes())); + webRequest = new ServletWebRequest(request); + + MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(MultipartFile[].class); + assertThatExceptionOfType(MissingServletRequestPartException.class).isThrownBy(() -> + resolver.resolveArgument(param, null, webRequest, null)); + } + @Test public void resolvePart() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -257,6 +279,19 @@ public class RequestParamMethodArgumentResolverTests { assertThat(result).isEqualTo(Arrays.asList(expected1, expected2)); } + @Test + public void resolvePartListMissing() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType("multipart/form-data"); + request.addPart(new MockPart("other", "Hello World 3".getBytes())); + webRequest = new ServletWebRequest(request); + + MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(List.class, Part.class); + assertThatExceptionOfType(MissingServletRequestPartException.class).isThrownBy(() -> + resolver.resolveArgument(param, null, webRequest, null)); + } + @Test public void resolvePartArray() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -280,6 +315,19 @@ public class RequestParamMethodArgumentResolverTests { assertThat(expected2).isEqualTo(parts[1]); } + @Test + public void resolvePartArrayMissing() throws Exception { + MockHttpServletRequest request = new MockHttpServletRequest(); + request.setMethod("POST"); + request.setContentType("multipart/form-data"); + request.addPart(new MockPart("other", "Hello World 3".getBytes())); + webRequest = new ServletWebRequest(request); + + MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Part[].class); + assertThatExceptionOfType(MissingServletRequestPartException.class).isThrownBy(() -> + resolver.resolveArgument(param, null, webRequest, null)); + } + @Test public void resolveMultipartFileNotAnnot() throws Exception { MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest();