gpt4 book ai didi

spring-boot - 无法让 Spring Boot 懒惰地解析多部分文件

转载 作者:行者123 更新时间:2023-12-04 13:03:08 25 4
gpt4 key购买 nike

我已经使用 Spring Initializr 创建了一个 Spring Boot 2 演示应用程序,并在下面添加了 Controller :

@Controller
@RequestMapping("/demo")
public class UploadController {
private final static Logger LOG = LoggerFactory.getLogger(UploadController.class);

@PostMapping("/upload")
public ResponseEntity<String> uploadFile(
@RequestParam("metadata") MultipartFile metadata,
@RequestParam("payload") MultipartFile payload) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Map metadataMap = mapper.readValue(metadata.getInputStream(), Map.class);
LOG.info("Received call to upload file {}", metadataMap.get("filename"));
LOG.info("File size: {}", payload.getBytes().length);
LOG.info("File {} successfully uploaded", metadataMap.get("filename"));
return ResponseEntity.ok().build();
}

}

然后我添加了一个包含此配置的 application.yaml 文件:
spring:
servlet:
multipart:
max-file-size: 2000000MB
max-request-size: 2000000MB
resolve-lazily: true

我的目标是让 Controller 解析并记录 metadata在开始读取 payload 之前的文件文件,但 resolve-lazily Boot 似乎忽略了设置:在读取整个主体之前,不会执行 Controller 内部的代码。

我使用下面的命令来测试 Controller :
curl -F metadata=@metadata.json -F payload=@payload.bin http://localhost:8080/demo/upload
我的代码/配置有什么问题吗?我是否理解设置的含义?

最佳答案

目前,如果你想避免一次性读取(和缓冲)整个 body,我认为 您必须提供自己的解析器 ,如答案 here 中所述.真正有趣的(但通常是不必要的)是以新的 MultipartResolver 实现的形式进行的。

interface MultipartResolver 记录了两个现有的实现。 ,并且都提供了一个函数 setResolveLazily(boolean) ( standard ), ( commons )。我已经尝试过两者,但似乎都不允许独立解析或流式传输多部分文件或参数。

Default is "false", resolving the multipart elements immediately, throwing corresponding exceptions at the time of the resolveMultipart(javax.servlet.http.HttpServletRequest) call. Switch this to "true" for lazy multipart parsing, throwing parse exceptions once the application attempts to obtain multipart files or parameters.



尽管文档中说了些什么,但我发现一旦您调用 resolveMultipart ,在调用返回之前解析和缓冲整个主体。我知道这一点是因为我可以看到正在创建的临时文件。

关于“我的代码有什么问题”的注释...

答案:是的,因为通过使用 @RequestParam在您的 Controller 被调用之前,您已经间接要求 Spring 提前解析您的参数。您应该能够做的是(如果文档正确)是从 Controller 内部独立请求参数:

配置(application.properties):
spring.servlet.multipart.enabled = true
spring.servlet.multipart.resolve-lazily = true

Controller :
@PostMapping(path = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Void> postUpload(HttpServletRequest rawRequest) {

multipartResolver.setResolveLazily(true); // unclear why this is exists
MultipartHttpServletRequest request = multipartResolver.resolveMultipart(rawRequest);

String p1 = request.getParameter("first-parameter");
String p2 = request.getParameter("second-parameter");
System.out.println("first-parameter="+p1+", second-parameter"+p2);

multipartResolver.cleanupMultipart(request);
return new ResponseEntity<Void>(HttpStatus.ACCEPTED);
}
resolve-lazily 的一个有用方面我发现它允许您为某些其余 Controller 编写自己的解析器,同时为其他 Controller 使用内置解析器(请参阅我的回答 here)。换句话说,您不必使用 spring.servlet.multipart.enabled = false让你的解析器工作。这是相对于 other advice 的一个小突破我以前见过的。

关于spring-boot - 无法让 Spring Boot 懒惰地解析多部分文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49234757/

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