文件上传与下载

文件上传与下载

在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");
    }

效果测试

文件上传


文件下载页面

相关推荐
seventeennnnn2 小时前
谢飞机的Java高级开发面试:从Spring Boot到分布式架构的蜕变之旅
spring boot·微服务架构·java面试·分布式系统·电商支付
超级小忍3 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
时间会给答案scidag4 小时前
报错 400 和405解决方案
vue.js·spring boot
Wyc724094 小时前
SpringBoot
java·spring boot·spring
ladymorgana6 小时前
【Spring Boot】HikariCP 连接池 YAML 配置详解
spring boot·后端·mysql·连接池·hikaricp
GJCTYU7 小时前
spring中@Transactional注解和事务的实战理解附代码
数据库·spring boot·后端·spring·oracle·mybatis
风象南8 小时前
SpringBoot敏感配置项加密与解密实战
java·spring boot·后端
写不出来就跑路9 小时前
暑期实习感悟与经验分享:从校园到职场的成长之路
java·开发语言·经验分享·spring boot
程序员张313 小时前
Maven编译和打包插件
java·spring boot·maven
灵犀学长15 小时前
EasyExcel之SheetWriteHandler:解锁Excel写入的高阶玩法
spring boot·excel