目的:为了解决前端直接根据文件连接地址下载导致的跨域问题;后端提供一个接口,根据前端传入的文件地址链接下载文件到本地再返回文件流给前端,从而避免跨域问题(代码已上线)
controller层代码:
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
public class controller{
@ApiOperation("下载文件")
@GetMapping("/front/downloadFile")
public ResponseEntity<Resource> downloadFile(@RequestParam String fileUrl) {
try {
Path downloadedFile = xxService.downloadFile(fileUrl);
Resource resource = new UrlResource(downloadedFile.toUri());
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + resource.getFilename());
return ResponseEntity.ok()
.headers(headers)
.contentLength(resource.contentLength())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
} catch (Exception e) {
log.error("下载文件异常,源文件地址是: {}。 异常信息是:{}", fileUrl, e.getMessage());
return ResponseEntity.status(500).body(null);
}
}
}
xxService层代码:
@Override
public Path downloadFile(String fileUrl) throws Exception {
URL url = new URL(fileUrl);
URLConnection connection = url.openConnection();
String fileName = determineFileName(fileUrl);
Path tempFile = Files.createTempFile("downloaded", ".tmp");
Files.copy(connection.getInputStream(), tempFile, StandardCopyOption.REPLACE_EXISTING);
Path targetFile = tempFile.resolveSibling(fileName);
// 该方法会move临时文件转换为目标文件
Files.move(tempFile, targetFile, StandardCopyOption.REPLACE_EXISTING);
log.info("文件下载成功后的保存路径是:{}", targetFile.toAbsolutePath());
return targetFile;
}
private String determineFileName(String fileUrl) {
String[] parts = fileUrl.split("/");
String fileName = parts[parts.length - 1];
if (fileName.contains(".")) {
return fileName;
} else {
return fileName + ".tmp"; // 默认添加 .tmp 扩展名
}
}
如果使用postman测试该接口,则会直接下载该接口;