gpt4 book ai didi

java - Spring Boot 多部分文件始终为空

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:22:16 26 4
gpt4 key购买 nike

我正在使用 Spring Boot version = '1.4.0.RC1' 和 Spring Boot Stormpath 1.0.2。

我正在尝试使用分段文件上传,但 Controller 中的 MultipartFile 始终为 null。

当我使用@RequestPart("file") 时,信息:"status":400,"error":"Bad Request","exception":"org.springframework.web.multipart.support.MissingServletRequestPartException ","message":"所需的请求部分'文件'不存在"

当我使用@RequestPart(name = "file", required = false) 时,该部分始终为空。

但是,如果我向 Controller 添加一个 HttpServletRequest 参数,我可以直接从请求中获取文件部分,所以我知道它确实存在。

这是 Controller ,在下面的代码中,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)

对正在发生的事情有什么想法吗?

最佳答案

您必须启用 Spring Multipart Resolver默认情况下,Spring 不启用多部分功能。

By default, Spring does no multipart handling, because some developerswant to handle multiparts themselves. You enable Spring multiparthandling by adding a multipart resolver to the web application’scontext.

在您的配置类中,您需要添加以下 bean:

@Bean
public MultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}

*** 更新 ***因为我之前的回答根据评论是不正确的。这是我能够成功运行的更新示例。

@SpringBootApplication
public class StackoverflowWebmvcSandboxApplication {
public static void main(String[] args) {
SpringApplication.run(StackoverflowWebmvcSandboxApplication.class, args);
}

@Controller
public class UploadPhoto {
@PostMapping("{username}/profilePhoto")
public ResponseEntity<String> saveProfilePhoto(@PathVariable("username") String username,
@RequestPart(name = "file", required = false) MultipartFile imageFile, HttpServletRequest request) {
String body = "MultipartFile";
if (imageFile == null) {
body = "Null MultipartFile";
}

return ResponseEntity.status(HttpStatus.CREATED).body(body);
}
}
}

这是一个非常基本的测试,没有什么特别的东西。然后我创建了一个 postman 请求,这里是示例 curl 调用:

curl -X POST -H "Cache-Control: no-cache" -H "Postman-Token: 17e5e6ac-3762-7d45-bc99-8cfcb6dc8cb5" -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW" -F "file=@" "http://localhost:8080/test/profilePhoto"

响应是 MultipartFile,这意味着它不是空的,并且在该行上进行调试显示变量中填充了我正在上传的图像。

关于java - Spring Boot 多部分文件始终为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39007726/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com