无法弄清楚如何在REST端点中使用FilePart获取文件的实际大小:
@RestController
public class SomeController {
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Long> fileSize(Mono<FilePart> filePart) {
//How to get size of FilePart?
// I'm not plan to create a File saving content of FilePart.
// Maybe it's possible somehow calculate size of all bytes.
return Mono.empty();
}
}
答案 0 :(得分:2)
当您将文件作为多部分表单数据上传时,会自动创建一个名为“ Content-Length”的请求标头,该标头是在发送请求时计算的。。
但是请注意,多部分内容长度略大于文件大小,这是由于创建了一些元数据,例如文件名,边界等。而且,无法,您无法估算此元数据的长度。解释是here。
因此,您可以通过以下方式获得尺寸(略有增加):
@RestController
public class SomeController {
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Long> fileSize(Mono<FilePart> filePart, @RequestHeader("Content-Length") long contentLength) {
System.out.println("Content length is:" + contentLength + "bytes");
return Mono.empty();
}
}
答案 1 :(得分:0)
在不先将文件保存到文件或将其缩小为InputStream或类似内容之前,我也无法弄清楚如何获得文件大小。
我最终要做的是向请求添加自定义标头。然后,您可以在控制器中读取标题:
@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Mono<Long> fileSize(Mono<FilePart> filePart, @RequestHeader("File-Size") Long fileSize) {
如果将新参数的类型更改为Map<String, String>
或MultiValueMap<String, String>
或HttpHeaders
,则将获得所有标头,而不仅仅是自定义标头。
如果您无法更改客户端的请求标头,并且不需要绝对精确的文件大小,则可以使用默认标头Content-Length
,该标头无论如何都已经发送了,但这将是几个字节。
答案 2 :(得分:0)
您可以使用Flux<DataBuffer>
访问文件部分中的filePart.content()
。使用这个。
filePart.content() // for one file, is a Flux with one element
.map(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()]; // <---- here you count the bytes you have.
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
String content = new String(bytes, StandardCharsets.UTF_8);
if (log.isTraceEnabled()) log.trace("File name: {}, content: {}", filePart.filename(),
content.length() > CONTENT_LENGTH_LIMIT ? content.substring(0, CONTENT_LENGTH_LIMIT) + "..." : content);
return content;
})