在Web应用中,文件下载功能是一个常见的需求,特别是当你需要提供用户下载各种类型的文件时。本文将演示如何使用Spring Boot框架来实现一个简单而强大的文件下载功能。我们将创建一个RESTful API,通过该API,用户可以下载问价为ZIP压缩文件。
首先,确保你已经创建了一个Spring Boot项目,并在项目中添加了所需的依赖。在这个示例中,我们将使用Spring Boot的Web模块和Spring的MVC框架。
创建一个名为DownloadController的RESTful控制器,用于处理文件下载请求。在这个控制器中,我们将定义一个downloadStudentWork方法,用于下载学生作品的ZIP压缩文件。具体文件流来源与具体业务。
- @RestController
- @RequestMapping("/download")
- public class DownloadController {
-
- @GetMapping("/studentWork")
- public ResponseEntity
downloadStudentWork() { - HttpHeaders headers = new HttpHeaders();
- headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
-
- String encodedFileName = "作品名称-学生姓名.zip";
- try {
- encodedFileName = URLEncoder.encode(encodedFileName, StandardCharsets.UTF_8.toString());
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- headers.setContentDispositionFormData("attachment", encodedFileName);
- StreamingResponseBody responseBody = outputStream -> {
- try (ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
-
- // 假设这是学生的作品内容视频文件流
- InputStream videoStream = getStudentVideoStream();
- addToZip(zipOut, videoStream, "作品视频.mkv");
-
- // 添加更多附件,如果有的话
-
- zipOut.finish();
- } catch (IOException e) {
- // 处理异常
- }
- };
-
- return new ResponseEntity<>(responseBody, headers, HttpStatus.OK);
- }
-
- private void addToZip(ZipOutputStream zipOut, InputStream inputStream, String fileName) throws IOException {
- ZipEntry zipEntry = new ZipEntry(fileName);
- zipOut.putNextEntry(zipEntry);
-
- byte[] buffer = new byte[1024];
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) != -1) {
- zipOut.write(buffer, 0, bytesRead);
- }
-
- zipOut.closeEntry();
- inputStream.close();
- }
-
- // 获取文件流
- private InputStream getStudentVideoStream() throws FileNotFoundException {
- // 附件信息
- FileInputStream inputStream = new FileInputStream("C:\\Users\\28111\\Videos\\2023-09-14 21-30-36.mkv");
- return inputStream;
- }
- }
当然,也可以用这种方式进行下载,也就是我们常用的void返回值这种方式
- package com.ly.cloud.controller.artworkEntries;
-
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import javax.servlet.http.HttpServletResponse;
- import java.io.*;
- import java.net.URLEncoder;
- import java.nio.charset.StandardCharsets;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipOutputStream;
-
- @RestController
- @RequestMapping("/download")
- public class DownloadController {
-
- @GetMapping("/studentWork")
- public void downloadStudentWork(HttpServletResponse response) {
- // 设置响应头信息
- response.setContentType("application/zip");
- String encodedFileName = "作品名称-学生姓名.zip";
- try {
- encodedFileName = URLEncoder.encode(encodedFileName, StandardCharsets.UTF_8.toString());
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- response.setHeader("Content-Disposition", "attachment; filename=" + encodedFileName);
- try (OutputStream outputStream = response.getOutputStream(); ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
-
- // 假设这是学生的作品内容视频文件流
- InputStream videoStream = getStudentVideoStream();
- addToZip(zipOut, videoStream, "作品视频.mkv");
-
- // 添加更多附件,如果有的话
- zipOut.finish();
- } catch (IOException e) {
- // 处理异常
- }
- }
-
- private void addToZip(ZipOutputStream zipOut, InputStream inputStream, String fileName) throws IOException {
- ZipEntry zipEntry = new ZipEntry(fileName);
- zipOut.putNextEntry(zipEntry);
-
- byte[] buffer = new byte[1024];
- int bytesRead;
- while ((bytesRead = inputStream.read(buffer)) != -1) {
- zipOut.write(buffer, 0, bytesRead);
- }
-
- zipOut.closeEntry();
- inputStream.close();
- }
-
- // 获取文件流
- private InputStream getStudentVideoStream() throws FileNotFoundException {
- // 附件信息
- FileInputStream inputStream = new FileInputStream("C:\\Users\\28111\\Videos\\2023-09-14 21-30-36.mkv");
- return inputStream;
- }
- }
下载的结果:

在downloadStudentWork方法中,我们设置HTTP响应头,以便告诉浏览器该响应是一个可下载的二进制文件。我们还将文件名进行URL编码,以确保文件名中的特殊字符不会导致问题。
使用Java的ZipOutputStream类,我们创建一个ZIP文件,并向其中添加学生作品的内容。在示例中,我们添加了一个假设的学生作品视频文件。
我们使用StreamingResponseBody来提供下载文件的流,以便文件能够逐块传输给客户端。这样可以有效地处理大文件,而不需要将整个文件加载到内存中。
以上是代码的大致结构,你可以在你的项目中实现它。请确保根据你的需求调整文件路径和名称。
最后,运行你的Spring Boot应用程序,访问/download/studentWork端点,你将能够下载学生作品的ZIP文件。
通过使用Spring Boot,我们很容易实现了一个强大的文件下载功能。你可以根据需要扩展这个示例,添加更多的附件或自定义功能,以满足你的应用程序需求。
希望这篇文章对你有所帮助,如果有任何问题或建议,请随时留言。