无法将 Apache Commons FileUpload 与 Spring Boot multipart.resolve 延迟使用
Cannot use Apache Commons FileUpload with Spring Boot multipart.resolve-lazily
我正在使用 Spring 引导框架构建 REST API。有一个端点,用户可以在其中上传一个大文件 (~1GB)。我正在使用来自 Apache Commons FileUpload 的 Streaming API。
我只想在该端点启用流式传输。因此,我将 Spring 引导配置如下:
spring.servlet.multipart.enabled = true
spring.servlet.multipart.resolve-lazily = true
spring.servlet.multipart.max-file-size = 2GB
spring.servlet.multipart.max-request-size = 2GB
这是我的终点:
@PostMapping(path = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> importData(HttpServletRequest request) throws IOException, FileUploadException {
System.out.println("Streaming...");
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
return ResponseEntity.badRequest().build();
}
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterStream = upload.getItemIterator(request);
while (iterStream.hasNext()) {
System.out.println("Iterating...");
FileItemStream item = iterStream.next();
if (!item.isFormField()) {
String name = item.getFieldName();
System.out.println("Field name is: " + name);
try (InputStream uploadedStream = item.openStream();
OutputStream out = new FileOutputStream("file.zip")) {
IOUtils.copy(uploadedStream, out);
}
} else {
try (InputStream stream = item.openStream()) {
String formFieldName = item.getFieldName();
String formFieldValue = Streams.asString(stream);
System.out.println(String.format("Form field found - %s: %s", formFieldName, formFieldValue));
}
}
}
return ResponseEntity.ok("Data streamed successfully.");
}
方法被调用,代码被执行。然而,FileItemIterator
是空的,因为 while
循环没有被执行。
如果我设置 spring.servlet.multipart.enabled = false
,此代码将完美运行。但我不想这样做,因为正如我所说,我不想全局禁用 Spring Boot Multipart Resolver,而只是在这个端点。
那么,我的代码有什么问题?为什么 FileItemIterator
是空的?
感谢您的帮助。
我解决了我的问题。
我认为问题出在 Spring StandardServletMultipartResolver
。当我切换到 CommonsMultipartResolver
(如下配置)时,我的代码运行完美。
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
resolver.setResolveLazily(true);
return resolver;
}
我正在使用 Spring 引导框架构建 REST API。有一个端点,用户可以在其中上传一个大文件 (~1GB)。我正在使用来自 Apache Commons FileUpload 的 Streaming API。
我只想在该端点启用流式传输。因此,我将 Spring 引导配置如下:
spring.servlet.multipart.enabled = true
spring.servlet.multipart.resolve-lazily = true
spring.servlet.multipart.max-file-size = 2GB
spring.servlet.multipart.max-request-size = 2GB
这是我的终点:
@PostMapping(path = "/import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> importData(HttpServletRequest request) throws IOException, FileUploadException {
System.out.println("Streaming...");
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) {
return ResponseEntity.badRequest().build();
}
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterStream = upload.getItemIterator(request);
while (iterStream.hasNext()) {
System.out.println("Iterating...");
FileItemStream item = iterStream.next();
if (!item.isFormField()) {
String name = item.getFieldName();
System.out.println("Field name is: " + name);
try (InputStream uploadedStream = item.openStream();
OutputStream out = new FileOutputStream("file.zip")) {
IOUtils.copy(uploadedStream, out);
}
} else {
try (InputStream stream = item.openStream()) {
String formFieldName = item.getFieldName();
String formFieldValue = Streams.asString(stream);
System.out.println(String.format("Form field found - %s: %s", formFieldName, formFieldValue));
}
}
}
return ResponseEntity.ok("Data streamed successfully.");
}
方法被调用,代码被执行。然而,FileItemIterator
是空的,因为 while
循环没有被执行。
如果我设置 spring.servlet.multipart.enabled = false
,此代码将完美运行。但我不想这样做,因为正如我所说,我不想全局禁用 Spring Boot Multipart Resolver,而只是在这个端点。
那么,我的代码有什么问题?为什么 FileItemIterator
是空的?
感谢您的帮助。
我解决了我的问题。
我认为问题出在 Spring StandardServletMultipartResolver
。当我切换到 CommonsMultipartResolver
(如下配置)时,我的代码运行完美。
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver resolver = new CommonsMultipartResolver();
resolver.setDefaultEncoding("UTF-8");
resolver.setResolveLazily(true);
return resolver;
}