三、WebFlux上传、下载、展示
一、文件上传
一个真实案例中,文件传到服务器后,要继续上传到 OSS,经实测 transferTo 的方案更完美。DataBufferUtils 的方案,传到服务器没问题,但继续上传到 OSS 后,图片总是只有上半身。
/**
* 文件上传
*/
@ApiOperation("轮播图 - 上传")
@PostMapping("/admin/chart/upload", consumes = [MediaType.MULTIPART_FORM_DATA_VALUE])
fun handleFileUpload(@RequestPart("file") filePart: Mono<FilePart>): Mono<Status> {
return filePart.map {
val tempFilePath = Files.createTempFile("chart-", it.filename())
// NOTE 方法一
it.transferTo(tempFilePath.toFile()).let {
val result = minioTemplate.putObject("chart/${tempFilePath.fileName}", tempFilePath)
Status.Ok(result)
}
// NOTE 方法二
// val channel = AsynchronousFileChannel.open(tempFilePath, StandardOpenOption.WRITE)
// DataBufferUtils.write(it.content(), channel, 0).subscribe().let {
// val result = minioTemplate.putObject("chart/${tempFilePath.fileName}", tempFilePath)
// Status.Ok(result)
// }
}
}
二、文件下载
/**
* Html、Video ok
*/
@GetMapping("/icloud/{id}/{fileName}")
fun ReadFile(@PathVariable id: Long, response: ServerHttpResponse): Mono<*> {
response.headers.set("Content-Disposition", "attachment; filename=$fileName") // 强制为下载
return Mono.just(FileSystemResource("/Users/xxx/Downloads/$fileName"))
}
支持断点续传,视频文件还支持 记忆播放(测试软件 IINA)。
三、文件显示
@GetMapping("/icloud/{id}/{fileName}")
fun showFile(@PathVariable id: Long, response: ServerHttpResponse): Mono<*> {
return icloudFileBS.getFile(id).map {
it.fullPath?.let { fullPath ->
response.headers.contentType = when (it.suffixName) {
"png", "jpg", "jpeg" -> MediaType.IMAGE_PNG
"htm", "html" -> MediaType.TEXT_HTML
"pdf", -> MediaType.APPLICATION_PDF
else -> MediaType.APPLICATION_PROBLEM_JSON
}
FileSystemResource(fullPath)
} ?: Status.BadRequest("没有文件路径信息")
}.defaultIfEmpty(Status.BadRequest("文件不存在!"))
}