本地 测试文件上传下载;
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package com.linke.product.interfaces.facade.menu;
|
||||
|
||||
import cn.hutool.core.io.resource.InputStreamResource;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.linke.product.application.service.menu.MenuApplicationService;
|
||||
import com.linke.product.domain.menu.entity.Menu;
|
||||
@@ -32,10 +31,12 @@ import org.springframework.web.multipart.MultipartFile;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -210,8 +211,58 @@ public class MenuApi extends BaseController {
|
||||
return AjaxResult.success(menuApplicationService.uploadMinio(file));
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 判断调用方IP是否为内网环境(192.168开头)
|
||||
*/
|
||||
private boolean isLocalNetwork(HttpServletRequest request) {
|
||||
String ip = request.getHeader("X-Forwarded-For");
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
// X-Forwarded-For 可能包含多个IP,取第一个
|
||||
if (ip != null && ip.contains(",")) {
|
||||
ip = ip.split(",")[0].trim();
|
||||
}
|
||||
return ip != null && ip.startsWith("192.168");
|
||||
}
|
||||
|
||||
/**
|
||||
* 本地上传文件到 D:/upload 目录
|
||||
*/
|
||||
private String uploadToLocal(MultipartFile file) throws IOException {
|
||||
String localUploadDir = "D:\\upload";
|
||||
File dir = new File(localUploadDir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String fileExtension = "";
|
||||
if (originalFilename != null && originalFilename.contains(".")) {
|
||||
fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
|
||||
}
|
||||
String fileName = UUID.randomUUID().toString() + fileExtension;
|
||||
File destFile = new File(dir, fileName);
|
||||
file.transferTo(destFile);
|
||||
// 返回本地文件路径标识,格式: LOCAL:D:/upload/xxx.ext
|
||||
return "LOCAL:" + destFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
@PostMapping("/upload")
|
||||
public AjaxResult<String> uploadFile(@RequestParam("file") MultipartFile file) {
|
||||
public AjaxResult<String> uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
|
||||
try {
|
||||
if (isLocalNetwork(request)) {
|
||||
String localPath = uploadToLocal(file);
|
||||
return AjaxResult.success(localPath);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
return AjaxResult.error("本地上传文件失败: " + e.getMessage());
|
||||
}
|
||||
String fileKey = fileStorageService.uploadFile(file);
|
||||
return AjaxResult.success(fileKey);
|
||||
}
|
||||
@@ -281,34 +332,36 @@ public class MenuApi extends BaseController {
|
||||
|
||||
|
||||
@PostMapping("/batchUpload")
|
||||
public AjaxResult batchUpload(@RequestParam("files") List<MultipartFile> files) {
|
||||
public AjaxResult batchUpload(@RequestParam("files") List<MultipartFile> files, HttpServletRequest request) {
|
||||
if (files == null || files.size() == 0) {
|
||||
return AjaxResult.error("上传文件不能为空");
|
||||
}
|
||||
List<String> fileUrls = new ArrayList<>();
|
||||
boolean localMode = isLocalNetwork(request);
|
||||
for (MultipartFile multipartFile : files) {
|
||||
String fileKey = fileStorageService.uploadFile(multipartFile);
|
||||
fileUrls.add(fileKey);
|
||||
if (localMode) {
|
||||
try {
|
||||
String localPath = uploadToLocal(multipartFile);
|
||||
fileUrls.add(localPath);
|
||||
} catch (IOException e) {
|
||||
return AjaxResult.error("本地上传文件失败: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
String fileKey = fileStorageService.uploadFile(multipartFile);
|
||||
fileUrls.add(fileKey);
|
||||
}
|
||||
}
|
||||
|
||||
return AjaxResult.success(fileUrls);
|
||||
}
|
||||
|
||||
@GetMapping("/download")
|
||||
public ResponseEntity<InputStreamResource> downloadFromOBS(
|
||||
public ResponseEntity<byte[]> downloadFromOBS(
|
||||
@RequestParam String obsUrl,
|
||||
@RequestParam String filename) {
|
||||
@RequestParam String filename,
|
||||
HttpServletRequest request) {
|
||||
|
||||
try {
|
||||
// 1. 连接到OBS临时URL
|
||||
URL url = new URL(obsUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
// 2. 获取输入流
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
|
||||
// 3. 设置响应头
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.add(HttpHeaders.CONTENT_DISPOSITION,
|
||||
"attachment; filename=\"" + filename + "\"");
|
||||
@@ -316,17 +369,49 @@ public class MenuApi extends BaseController {
|
||||
headers.add(HttpHeaders.PRAGMA, "no-cache");
|
||||
headers.add(HttpHeaders.EXPIRES, "0");
|
||||
|
||||
// 4. 根据文件类型设置Content-Type
|
||||
// 判断是否为内网环境,从本地文件读取
|
||||
if (isLocalNetwork(request) && obsUrl != null && obsUrl.startsWith("LOCAL:")) {
|
||||
String localFilePath = obsUrl.substring("LOCAL:".length());
|
||||
File localFile = new File(localFilePath);
|
||||
if (!localFile.exists()) {
|
||||
throw new RuntimeException("本地文件不存在: " + localFilePath);
|
||||
}
|
||||
byte[] fileBytes = Files.readAllBytes(localFile.toPath());
|
||||
String contentType = Files.probeContentType(localFile.toPath());
|
||||
MediaType mediaType = contentType != null ?
|
||||
MediaType.valueOf(contentType) :
|
||||
MediaType.APPLICATION_OCTET_STREAM;
|
||||
headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileBytes.length));
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.contentType(mediaType)
|
||||
.body(fileBytes);
|
||||
}
|
||||
|
||||
// 连接OBS临时URL下载
|
||||
URL url = new URL(obsUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, bytesRead);
|
||||
}
|
||||
inputStream.close();
|
||||
byte[] fileBytes = baos.toByteArray();
|
||||
|
||||
String contentType = connection.getContentType();
|
||||
MediaType mediaType = contentType != null ?
|
||||
MediaType.valueOf(contentType) :
|
||||
MediaType.APPLICATION_OCTET_STREAM;
|
||||
|
||||
// 5. 返回流式响应
|
||||
headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileBytes.length));
|
||||
return ResponseEntity.ok()
|
||||
.headers(headers)
|
||||
.contentType(mediaType)
|
||||
.body(new InputStreamResource(inputStream));
|
||||
.body(fileBytes);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("下载文件失败", e);
|
||||
@@ -340,8 +425,31 @@ public class MenuApi extends BaseController {
|
||||
public ResponseEntity<StreamingResponseBody> downloadStreaming(
|
||||
@RequestParam String bucketName,
|
||||
@RequestParam String objectKey,
|
||||
@RequestParam String filename) {
|
||||
@RequestParam String filename,
|
||||
HttpServletRequest request) {
|
||||
|
||||
// 判断是否为内网环境,从本地文件读取
|
||||
if (isLocalNetwork(request) && objectKey != null && objectKey.startsWith("LOCAL:")) {
|
||||
String localFilePath = objectKey.substring("LOCAL:".length());
|
||||
File localFile = new File(localFilePath);
|
||||
return ResponseEntity.ok()
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
"attachment; filename=\"" + filename + "\"")
|
||||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
.contentLength(localFile.length())
|
||||
.body(outputStream -> {
|
||||
try (InputStream inputStream = new FileInputStream(localFile)) {
|
||||
byte[] buffer = new byte[8192];
|
||||
int bytesRead;
|
||||
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, bytesRead);
|
||||
}
|
||||
outputStream.flush();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// OBS方式下载
|
||||
return ResponseEntity.ok()
|
||||
.header(HttpHeaders.CONTENT_DISPOSITION,
|
||||
"attachment; filename=\"" + filename + "\"")
|
||||
@@ -349,19 +457,9 @@ public class MenuApi extends BaseController {
|
||||
.body(outputStream -> {
|
||||
ObsClient obsClient1 = null;
|
||||
try {
|
||||
System.out.println(
|
||||
"AccessKey:" + obsProperties.getAccessKey() +
|
||||
"SecretKey:" + obsProperties.getSecretKey()
|
||||
+ "Endpoint:" + obsProperties.getEndpoint()
|
||||
);
|
||||
logger.error(
|
||||
"AccessKey:" + obsProperties.getAccessKey() +
|
||||
"SecretKey:" + obsProperties.getSecretKey()
|
||||
+ "Endpoint:" + obsProperties.getEndpoint()
|
||||
);
|
||||
obsClient1 = new ObsClient(obsProperties.getAccessKey(), obsProperties.getSecretKey(), obsProperties.getEndpoint());
|
||||
GetObjectRequest request = new GetObjectRequest(bucketName, objectKey);
|
||||
ObsObject obsObject = obsClient1.getObject(request);
|
||||
GetObjectRequest req = new GetObjectRequest(bucketName, objectKey);
|
||||
ObsObject obsObject = obsClient1.getObject(req);
|
||||
|
||||
try (InputStream inputStream = obsObject.getObjectContent()) {
|
||||
byte[] buffer = new byte[8192];
|
||||
|
||||
Reference in New Issue
Block a user