I am using Spring Boot version = '1.4.0.RC1' with Spring Boot Stormpath 1.0.2.
I am trying to use multi-page file upload, but MultipartFile is always null in the controller.
When I use @RequestPart ("file"), information: "status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present"
When I use @RequestPart (name = "file", required = false), this part is always null.
However, if I add the HttpServletRequest argument to the controller, I can get part of the file directly from the request, so I know that it is actually present.
This is the controller and in the code below checkNotNull(part) always succeeds, and checkNotNull(imageFile) always fails:
@PostMapping("{username}/profilePhoto") public ResponseEntity<?> saveProfilePhoto(@PathVariable("username") String username, @RequestPart(name = "file", required = false) MultipartFile imageFile, HttpServletRequest request) { try { Part part = request.getPart("file"); checkNotNull(part); checkNotNull(imageFile); } catch (IOException | ServletException ex) { throw InternalServerErrorException.create(); } // Transfer the multipart file to a temp file File tmpFile; try { tmpFile = File.createTempFile(TMP_FILE_PREFIX, null); imageFile.transferTo(tmpFile); } catch (IOException ex) { log.error("Failed to create temp file", ex); throw InternalServerErrorException.create(); } // Execute the use case updateUserProfilePhoto.execute(username, tmpFile); // Delete the temp file FileUtils.deleteQuietly(tmpFile); return ResponseEntity.status(HttpStatus.CREATED).build(); }
My integration test uses a modification:
@Multipart @POST("users/{username}/profilePhoto") Call<Void> uploadProfilePhoto(@Path("username") String username, @Part("file") RequestBody profilePhoto); ... @Test public void saveProfilePhoto_shouldSavePhoto() throws IOException { // Given String usernamme = usernames[0]; Resource testImageResource = context.getResource("classpath:images/test_image.jpg"); File imageFile = testImageResource.getFile(); RequestBody body = RequestBody.create(okhttp3.MediaType.parse("image/*"), imageFile); // When Response<Void> response = getTestApi().uploadProfilePhoto(usernamme, body).execute(); // Then assertThat(response.code()).isEqualTo(201); }
I use auto-tuning, so my only custom configuration class configures the Stormpath:
@Configuration public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.apply(stormpath()); } }
UPDATE: This is an outgoing request. I'm not sure how to enable logging in the multiprocessor resolver itself.
2016-08-18 14:44:14.714 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : --> POST http://localhost:8080/users/user1/profilePhoto http/1.1 2016-08-18 14:44:14.714 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : Content-Type: multipart/form-data; boundary=fe23ef21-3413-404c-a260-791c6921b2c6 2016-08-18 14:44:14.715 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : Content-Length: 181212 2016-08-18 14:44:14.715 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : Accept: application/json 2016-08-18 14:44:14.715 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : Authorization: Bearer [token] 2016-08-18 14:44:14.715 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : 2016-08-18 14:44:14.735 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : --fe23ef21-3413-404c-a260-791c6921b2c6 Content-Disposition: form-data; name="file" Content-Transfer-Encoding: binary Content-Type: image/* Content-Length: 180999 file data --fe23ef21-3413-404c-a260-791c6921b2c6-- 2016-08-18 14:44:14.762 DEBUG 13088 --- [ main] ctserver.web.testutil.TestConfig$1 : --> END POST (181212-byte body)
Any ideas on what's going on?