网站首页 > java教程 正文
在我们项目开发中,大文件上传与下载是一项常见的功能需求,特别是在高并发和用户体验要求高的场景下。Vue.js作为一款流行的前端框架,以其响应式的数据绑定和组件化的优势使得前端交互更加流畅;而Java后端凭借其稳定性和高性能,是构建健壮服务端的理想选择。
老规矩,多余话不说,直接上实现思路与代码。
大文件异步上传功能实现思路:
前端:
- 使用HTML5的FormData API封装文件信息,可通过new FormData()并将file对象添加到表单数据中。
- 利用axios或其他HTTP库发送POST请求,设置请求头Content-Type为'multipart/form-data'以适应文件上传。
- 实现进度条功能,通过监听xhr.upload.onprogress事件实时更新上传进度。
后端:
- 接收multipart请求,使用如Commons FileUpload或Spring Boot自带的MultipartFile接口解析文件。
- 文件暂存于临时目录或直接上传至云存储服务,如OSS或S3。
- 后端处理完成后返回相应状态码和信息,以便前端显示上传结果。
大文件异步下载功能实现思路:
前端:
- 前端通过点击事件触发下载动作,向后端发送请求获取文件下载链接或者流式响应。
- 对于较大的文件,可以创建隐藏的iframe或者a标签配合download属性,由服务器返回合适的Content-Disposition头来触发浏览器下载。
后端:
- 根据请求生成文件下载的响应,设置适当的Content-Type和Content-Disposition头部信息。
- 若采用流式传输,可使用Servlet的OutputStream逐块读取文件并发送给客户端,减轻内存压力。
思路有了,直接上代码:
前端Vue部分(使用axios):
前端Vue部分,我们将创建一个简单的上传组件,该组件包括一个文件输入框和一个进度条,用于展示上传进度。这里假设你已经设置了axios,并全局导入。
<!-- Vue组件 -->
<template>
<div>
<input type="file" @change="handleFileSelect" />
<div v-if="uploadProgress > 0">
上传进度: {{ uploadProgress }}%
<progress :value="uploadProgress" max="100"></progress>
</div>
</div>
</template>
<script>
export default {
data() {
return {
uploadProgress: 0,
selectedFile: null,
};
},
methods: {
handleFileSelect(event) {
this.selectedFile = event.target.files[0];
let formData = new FormData();
formData.append('file', this.selectedFile);
axios.post('/api/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: (progressEvent) => {
this.uploadProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
}
})
.then(response => {
console.log('File uploaded successfully:', response.data);
// 清除上传进度并重置文件选择
this.uploadProgress = 0;
this.selectedFile = null;
})
.catch(error => {
console.error('Error uploading file:', error);
this.uploadProgress = 0;
});
},
},
};
</script>
// Vue组件内方法
async handleFileUpload(file) {
const formData = new FormData();
formData.append('file', file); // 'file' 是从<input type="file">元素获取的文件对象
const config = {
headers: {
'Content-Type': 'multipart/form-data'
},
onUploadProgress: progressEvent => {
this.progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
}
};
try {
const response = await axios.post('/api/upload', formData, config);
console.log(response.data); // 处理后端返回的信息
} catch (error) {
console.error(error);
}
}
后端Java Spring Boot部分(接收文件):
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.http.ResponseEntity;
@RestController
public class FileController {
@PostMapping("/api/upload")
public ResponseEntity<String> handleFileUpload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return ResponseEntity.badRequest().body("Failed to upload, no file content found.");
}
// 获取文件名及扩展名
String originalFilename = file.getOriginalFilename();
// 将文件保存到指定路径,这里仅为示例,生产环境中需要考虑磁盘空间、文件命名策略等问题
try {
Path path = Paths.get(UPLOADED_FOLDER_PATH + originalFilename);
Files.write(path, file.getBytes());
return ResponseEntity.ok("File uploaded successfully");
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to upload the file: " + e.getMessage());
}
}
}
对于大文件下载,通常后端会提供一个下载链接,前端接收到此链接后,可以通过创建隐藏的<a>标签模拟点击下载,或者利用Blob对象在浏览器中创建可下载的URL。后端可能提供的不是一个链接,而是直接返回带有正确Content-Disposition头的响应体,触发浏览器下载行为。
后端Java Spring Boot部分(提供文件下载):
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
@GetMapping("/api/download/{filename}")
public ResponseEntity<StreamingResponseBody> downloadFile(@PathVariable String filename) throws IOException {
// 这里假设已知文件存放的实际路径
File file = new File(DOWNLOAD_FOLDER_PATH + filename);
if (!file.exists()) {
return ResponseEntity.notFound().build();
}
StreamingResponseBody stream = outputStream -> {
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[4096];
int n;
while ((n = fis.read(buffer)) != -1) {
outputStream.write(buffer, 0, n);
}
fis.close();
};
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + filename + "\"");
return ResponseEntity.ok()
.headers(headers)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(stream);
}
在这个例子中,当用户选择文件后,handleFileSelect方法会被调用,开始上传文件。通过监听onUploadProgress事件,我们可以获取到文件上传的进度,并实时更新到视图层展示给用户。上传完成后,清除上传进度,并允许用户再次选择文件进行上传。如果在上传过程中发生错误,也会捕获异常并显示错误信息。
思路和代码都说完,简单说几句,以上结合Vue前端技术和Java后端技术,我们成功地搭建了一套高效可靠的大文件异步上传下载解决方案。前端通过良好的用户界面提供了直观的上传下载进度反馈,而后端则确保了数据的高效处理与安全传输。这套方案不仅适用于一般企业级应用,也能应对大数据处理的复杂场景。当然,在实际部署和应用中还需注意权限控制、错误处理以及性能优化等方面,以保证系统的整体稳定性与用户体验。
如果有用,请点赞+关注!
猜你喜欢
- 2024-10-21 Spring WEB工程整合使用FTP,ftp文本文件解析入库,文件上传下载
- 2024-10-21 使用SFTP跟服务器传输文件(怎么用sftp上传文件到服务器)
- 2024-10-21 Ubuntu 下安装 JDK17(ubuntu中安装jdk)
- 2024-10-21 JasperReport生成pdf文件 Java开发pdf文件 pdf文件生成及下载
- 2024-10-21 用JavaEE实现前后台交互的文件上传与下载,适合小白入门练手!
- 2024-10-21 JAVA 大文件上传解决方案(500M以上)
- 2024-10-21 《数据结构与算法分析Java语言描述》PDF文件免费下载
- 2024-10-21 CDH安装系统环境准备——系统版本和安装包下载地址指南
- 2024-10-21 jar文件怎么打开(base.apk.1文件怎么打开)
- 2024-10-21 Java 实现 FastDFS 实现文件的上传、下载、删除
你 发表评论:
欢迎- 07-21如何将 iPhone 中的联系人导出到 Excel/CSV?
- 07-21sql查询的字段数据中有逗号。放到csv文件会分开,如何解决?
- 07-21在 WebAPI 里生成 csv zip 文件(webapi怎么发布在iis上)
- 07-21如何把csv格式转换成Excel格式(csv格式怎么转换)
- 07-21如何将高程导出为XYZ或CSV高程点(如何将高程数据导入cad)
- 07-21使用python把csv汇总成excel(python怎么将csv文件中的列存入列表)
- 07-21解决PHP导出CSV文件中文乱码问题(php导出excel文件)
- 07-21使用vba将Excel 文件转成 CSV 文件
- 最近发表
-
- 如何将 iPhone 中的联系人导出到 Excel/CSV?
- sql查询的字段数据中有逗号。放到csv文件会分开,如何解决?
- 在 WebAPI 里生成 csv zip 文件(webapi怎么发布在iis上)
- 如何把csv格式转换成Excel格式(csv格式怎么转换)
- 如何将高程导出为XYZ或CSV高程点(如何将高程数据导入cad)
- 使用python把csv汇总成excel(python怎么将csv文件中的列存入列表)
- 解决PHP导出CSV文件中文乱码问题(php导出excel文件)
- 使用vba将Excel 文件转成 CSV 文件
- python爬虫25 | 爬取的数据怎么保存?CSV了解一下
- MySQL 导出数据(mysql 导出数据 判断成功)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)