【发布时间】:2016-12-24 18:23:30
【问题描述】:
我正在使用 Spring Boot 版本 = '1.4.0.RC1' 和 Spring Boot Stormpath 1.0.2。
我正在尝试使用多部分文件上传,但控制器中的 MultipartFile 始终为空。
当我使用@RequestPart("file") 时,信息:"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException","message":"Required request part 'file' is not present"
当我使用@RequestPart(name = "file", required = false) 时,该部分始终为空。
但是,如果我向控制器添加一个 HttpServletRequest 参数,我可以直接从请求中获取文件部分,因此我知道它确实存在。
这是控制器,在下面的代码中 checkNotNull(part) 总是成功,checkNotNull(imageFile) 总是失败:
@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();
}
我的集成测试使用改造:
@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);
}
我正在使用自动配置,所以我唯一的自定义配置类配置了 Stormpath:
@Configuration
public class SpringSecurityWebAppConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.apply(stormpath());
}
}
更新: 这是传出请求。我不确定如何在多部分解析器本身中启用日志记录。
2016-08-18 14:44:14.714 DEBUG 13088 --- [ main] c.t.server.web.testutil.TestConfig$1 : --> POST http://localhost:8080/users/user1/profilePhoto http/1.1
2016-08-18 14:44:14.714 DEBUG 13088 --- [ main] c.t.server.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] c.t.server.web.testutil.TestConfig$1 : Content-Length: 181212
2016-08-18 14:44:14.715 DEBUG 13088 --- [ main] c.t.server.web.testutil.TestConfig$1 : Accept: application/json
2016-08-18 14:44:14.715 DEBUG 13088 --- [ main] c.t.server.web.testutil.TestConfig$1 : Authorization: Bearer [token]
2016-08-18 14:44:14.715 DEBUG 13088 --- [ main] c.t.server.web.testutil.TestConfig$1 :
2016-08-18 14:44:14.735 DEBUG 13088 --- [ main] c.t.server.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] c.t.server.web.testutil.TestConfig$1 : --> END POST (181212-byte body)
对正在发生的事情有任何想法吗?
【问题讨论】:
-
你能包括请求有效载荷的样子吗?甚至可以将调试级别日志记录添加到您正在使用的
MultipartResolver中,以查看它是否正在解释请求的多部分组件? -
@shawn-clark 这是传出请求。我不确定如何在多部分解析器本身中启用日志记录。请求标头:接受:application/json 授权:Bearer [auth token] 请求正文:--56436527-d311-4d26-8e67-27fdf6f0edb8 内容处置:form-data; name="file" Content-Transfer-Encoding: binary Content-Type: image/* Content-Length: 180999 [... binary...] --56436527-d311-4d26-8e67-27fdf6f0edb8--
-
当您使用 spring boot 1.4 时,您可以使用我的解决方案,它可以工作
标签: java spring-mvc spring-boot retrofit multipart