文件上传与下载

文件上传与下载

在Spring Boot中实现文件上传与下载的功能通常涉及前端和后端的交互。前端负责提供文件选择的界面和触发上传/下载操作,后端则负责处理文件上传的请求、存储文件,以及处理文件下载的请求并发送文件内容给前端。

文件上传

  1. 前端:使用HTML表单或JavaScript库来选择文件并发送POST请求到后端。
  2. 后端:在Spring Boot中,你可以使用MultipartFile接口来处理文件上传。下面是一个简单的示例。

前端

html 复制代码
<div class="container">
    <h1 class="title">文件上传</h1>
    <form action="/uploadFile" enctype="multipart/form-data" method="post">
        <div class="upload-area">
            <input type="file" id="fileInput" name="files"
             multiple onchange="updateFileList(this)">
            <button type="submit" >上传文件</button>
        </div>
        <ul id="fileList" class="file-list"></ul>
    </form>

        <p id="uploadSuccess" class="upload-success" 
        th:text="${uploadStatus}">文件上传成功!</p>

</div>

后端Controller示例:

实体表

java 复制代码
@Data
@TableName("attachment")
public class Attachment {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String fileName;
    private String storagePath;
}

上传页面访问方法

java 复制代码
@Controller
public class FileController {

    @Autowired
    private IAttachmentService attachmentService;

    // 向文件上传页面跳转
    @GetMapping("/toUpload")
    public String upload(){
        return "upload";
    }
}

文件上传方法

java 复制代码
  //文件上传管理
    @PostMapping("/uploadFile")
    public String uploadFile(MultipartFile[] files, Model model){
        // 默认文件上传成功,并返回状态信息
        model.addAttribute("uploadStatus", "上传成功!");
        for(MultipartFile file:files){
            // 获取文件名以及后缀名
            String fileName = file.getOriginalFilename();
            // 重新生成文件名(根据具体情况生成对应文件名)
            fileName = UUID.randomUUID()+"_"+fileName;
            // 指定上传文件本地存储目录,不存在需要提前创建
            String dirPath = "D:/file/";
            File filePath = new File(dirPath);
            if(!filePath.exists()){
                filePath.mkdirs();
            }
            try {
                file.transferTo(new File(dirPath+fileName));
                //文件信息存储到数据库中
                Attachment attachment = new Attachment();
                attachment.setFileName(file.getOriginalFilename());
                attachment.setStoragePath(fileName);
                attachmentService.save(attachment);
            } catch (Exception e) {
                e.printStackTrace();
                // 上传失败,返回失败信息
                model.addAttribute("uploadStatus","上传失败: "+e.getMessage());
            }
        }
        // 携带上传状态信息回调到文件上传页面
        return "upload";
    }

文件下载

前端:用户点击下载链接或按钮,触发GET请求到后端。

后端:在后端Controller中处理GET请求,读取文件内容,并将其作为HTTP响应返回给前端。

前端

html 复制代码
    <h1>文件下载列表</h1>  
    <div class="file-list" >
        <div class="file-item" th:each="attachment:${list}">
            <p class="file-name" th:text="${attachment.fileName}">文件名1</p>
            <a th:href="${'/download?id='+attachment.id}" 
            class="download-button" download>下载</a>
        </div>
        <!-- 添加更多文件项 -->  
    </div>  

下载页面访问方法

java 复制代码
 /**
     * 向文件下载页面跳转
     */
    @GetMapping("/toDownload")
    public String toDownload(Model model){
        //查询文件信息
        List<Attachment> list = attachmentService.list();
        model.addAttribute("list",list);
        return "download";
    }

文件下载方法

java 复制代码
     // 文件下载
    @GetMapping("/download")
    public ResponseEntity<Resource> fileDownload(HttpServletRequest request,Long id)
     throws Exception{
        //获取文件数据对象
        Attachment attachment = attachmentService.getById(id);
        // 指定要下载的文件根路径
        String dirPath = "D:/file/";
        // 创建该文件对象
        File file = new File(dirPath + attachment.getStoragePath());
        // 设置响应头
        HttpHeaders headers = new HttpHeaders();
        // 通知浏览器以下载方式打开(下载前对文件名进行转码)
        String filename=getFilename(request,attachment.getFileName());
        headers.setContentDispositionFormData("attachment",filename);
        // 定义以流的形式下载返回文件数据
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        InputStreamResource inputStreamResource =
         new InputStreamResource(Files.newInputStream(file.toPath()));
        return new ResponseEntity<>(inputStreamResource, headers, HttpStatus.OK);
    }

文件名乱码处理方法

java 复制代码
 // 根据浏览器的不同进行编码设置,返回编码后的文件名
    private String getFilename(HttpServletRequest request, String filename)
            throws Exception {
        // IE不同版本User-Agent中出现的关键词
        String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};
        // 获取请求头代理信息
        String userAgent = request.getHeader("User-Agent");
        for (String keyWord : IEBrowserKeyWords) {
            if (userAgent.contains(keyWord)) {
                //IE内核浏览器,统一为UTF-8编码显示,并对转换的+进行更正
                return URLEncoder.encode(filename, "UTF-8").replace("+"," ");
            }
        }
        //火狐等其它浏览器统一为ISO-8859-1编码显示
        return new String(filename.getBytes("UTF-8"), "ISO-8859-1");
    }

效果测试

文件上传


文件下载页面

相关推荐
Jabes.yang1 小时前
Java面试场景:从Spring Web到Kafka的音视频应用挑战
大数据·spring boot·kafka·spring security·java面试·spring webflux
程序员小凯4 小时前
Spring Boot性能优化详解
spring boot·后端·性能优化
tuine4 小时前
SpringBoot使用LocalDate接收参数解析问题
java·spring boot·后端
番茄Salad5 小时前
Spring Boot项目中Maven引入依赖常见报错问题解决
spring boot·后端·maven
摇滚侠6 小时前
Spring Boot 3零基础教程,yml配置文件,笔记13
spring boot·redis·笔记
!if6 小时前
springboot mybatisplus 配置SQL日志,但是没有日志输出
spring boot·sql·mybatis
阿挥的编程日记7 小时前
基于SpringBoot的影评管理系统
java·spring boot·后端
java坤坤7 小时前
Spring Boot 集成 SpringDoc OpenAPI(Swagger)实战:从配置到接口文档落地
java·spring boot·后端
摇滚侠8 小时前
Spring Boot 3零基础教程,整合Redis,笔记12
spring boot·redis·笔记
荣淘淘8 小时前
互联网大厂Java求职面试全景实战解析(涵盖Spring Boot、微服务及云原生技术)
java·spring boot·redis·jwt·cloud native·microservices·interview