90 lines
3.0 KiB
Java
90 lines
3.0 KiB
Java
package com.guahao.h5.zip;
|
||
|
||
|
||
import org.springframework.http.*;
|
||
import org.springframework.web.bind.annotation.*;
|
||
import org.springframework.core.io.InputStreamResource;
|
||
|
||
import java.io.IOException;
|
||
import java.io.RandomAccessFile;
|
||
import java.nio.file.*;
|
||
import java.util.Objects;
|
||
|
||
@RestController
|
||
@RequestMapping("/find")
|
||
/**
|
||
* 对账平台接口
|
||
*/
|
||
public class DownloadZipController {
|
||
|
||
// ZIP 文件所在目录
|
||
private static final String DOWNLOAD_DIR = "/root/ccbwlpt/download";
|
||
|
||
/**
|
||
* 接口:下载指定 ZIP 文件
|
||
* URL: GET /api/download/{fileName}
|
||
*/
|
||
@GetMapping("/download/{fileName}")
|
||
public ResponseEntity<InputStreamResource> downloadZip(
|
||
@PathVariable String fileName) {
|
||
|
||
// 1. 构建完整文件路径
|
||
Path filePath = Paths.get(DOWNLOAD_DIR, fileName);
|
||
|
||
// 2. 验证文件是否存在且为普通文件
|
||
if (!Files.exists(filePath)) {
|
||
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||
.body(null);
|
||
}
|
||
if (!Files.isRegularFile(filePath)) {
|
||
return ResponseEntity.badRequest()
|
||
.body(null);
|
||
}
|
||
|
||
// 3. 验证文件确实是 ZIP(可选安全检查)
|
||
if (!isZipFile(filePath)) {
|
||
return ResponseEntity.badRequest()
|
||
.header("X-Error", "File is not a ZIP file")
|
||
.body(null);
|
||
}
|
||
|
||
try {
|
||
// 4. 打开输入流
|
||
InputStreamResource resource = new InputStreamResource(Files.newInputStream(filePath));
|
||
|
||
// 5. 构造响应头
|
||
HttpHeaders headers = new HttpHeaders();
|
||
headers.add("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
|
||
headers.add("Content-Type", "application/zip");
|
||
headers.setContentLength(Files.size(filePath));
|
||
|
||
return ResponseEntity.ok()
|
||
.headers(headers)
|
||
.contentLength(Files.size(filePath))
|
||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||
.body(resource);
|
||
|
||
} catch (IOException e) {
|
||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||
.header("X-Error", "Failed to read file: " + e.getMessage())
|
||
.body(null);
|
||
} catch (SecurityException e) {
|
||
return ResponseEntity.status(HttpStatus.FORBIDDEN)
|
||
.header("X-Error", "Permission denied: " + e.getMessage())
|
||
.body(null);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 简单判断是否为 ZIP 文件(检查文件头)
|
||
*/
|
||
private boolean isZipFile(Path path) {
|
||
try (RandomAccessFile raf = new RandomAccessFile(path.toFile(), "r")) {
|
||
if (raf.length() < 4) return false;
|
||
int magic = raf.readInt();
|
||
return magic == 0x504B0304 || magic == 0x504B0506 || magic == 0x504B0708;
|
||
} catch (IOException e) {
|
||
return false;
|
||
}
|
||
}
|
||
} |