Springboot文件下载方式(直接下载)

package com.example.demo.controller;

import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@RequestMapping("/upload3")
@RestController
public class uploadController {
    //定义分片有多大
    private  final  static  long PER_PAGE=1024l*1024l*50l;
    //设置分片存储的临时目录
    private  final  static  String DOWN_PATH="C:\\Users\\Lenovo\\Desktop\\lianxi";
    //下载文件的地址
    private  final  static String url="http://localhost:8080/upload3/downLoad/";
    //文件存放的位置
    private  final  static String pathfile=System.getProperty("user.dir")+"\\static\\upload\\";
    ExecutorService pool= Executors.newFixedThreadPool(10);
    //文件大小文件名字
    // 探测 获取文件信息
    // 多线程分片下载

    //最后一个分片下载完 始合并
    @RequestMapping("/downLoadFile/{filename}")
    public void downLoadFile(@PathVariable("filename") String filename) throws IOException, InterruptedException {
        FileInfo fileInfo = download(0, 10, -1, null,filename);
        if (fileInfo!=null) {
            long pages= fileInfo.fSize/PER_PAGE;

            for(long i=0;i<=pages;i++){
                pool.submit(new DownLoad(i* PER_PAGE,(i+1)*PER_PAGE-1,i,fileInfo.fName,filename));
           }
        }


    }
    class DownLoad implements Runnable{
        long start;
        long end;
        long page;
        String fName;
        String fileName;

        public DownLoad(long start, long end, long page, String fName, String fileName) {
            this.start = start;
            this.end = end;
            this.page = page;
            this.fName = fName;
            this.fileName = fileName;
        }

        @Override
        public void run() {
            try {
                download(start,end,page,fName,fileName);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }
    class  FileInfo{
        long fSize;
        String fName;

        public FileInfo(long fSize, String fName) {
            this.fSize = fSize;
            this.fName = fName;
        }
    }
    //结束的位置开始的位置=分片大小
    private FileInfo download(long start,long end,long page,String fName,String fileName) throws IOException, InterruptedException {
        File file = new File(DOWN_PATH, page + "-" + fName);
        if (file.exists() && page!=-1 &&file.length()==PER_PAGE){
            return  null;
        }
        HttpClient client = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url+fileName);
        httpGet.setHeader("Range","bytes="+start+"-"+end);
        HttpResponse response = client.execute(httpGet);
        String fSize = response.getFirstHeader("fSize").getValue();
        fName= URLDecoder.decode(response.getFirstHeader("fName").getValue(),"utf-8");

        HttpEntity entity = response.getEntity();
        InputStream is = entity.getContent();
        FileOutputStream fos = new FileOutputStream(file);
        byte[] buffer = new byte[1024];
        int ch;
        while ((ch=is.read(buffer))!=-1){
            fos.write(buffer,0,ch);
        }
        is.close();
        fos.flush();
        fos.close();
        if (end -Long.valueOf(fSize)>0){
            mergeFile(fName,page);
        }
        return new FileInfo(Long.valueOf(fSize),fName);
    }

    private void mergeFile(String fName, long page) throws IOException, InterruptedException {
        File file=new File(DOWN_PATH,fName);
        BufferedOutputStream os = new BufferedOutputStream(new FileOutputStream(file));
        for (int i = 0; i <=page; i++) {
            File temFile = new File(DOWN_PATH, i + "-" + fName);
            while (!file.exists()||(i!=page && temFile.length()<PER_PAGE)){
                Thread.sleep(100);
            }
            byte[] bytes=  FileUtils.readFileToByteArray(temFile);
            os.write(bytes);
            os.flush();
            temFile.delete();
        }
        File file1=new File(DOWN_PATH,-1+"-null");
        file1.delete();
        os.flush();
        os.close();
    }

    @RequestMapping("/downLoad/{filename}")
    public void downLoadFile(@PathVariable("filename") String filename, HttpServletResponse response, HttpServletRequest request) throws IOException {
        //文件存在的路径
        String path = pathfile+filename;
        //String path="D:\\java 录屏\\20231216_183319.mp4";
        File file = new File(path);
        if(!file.exists()){
            return;
        }
        //设置编码
        response.setCharacterEncoding("utf-8");
        //输入输出对象
        InputStream is=null;
        OutputStream os=null;
        //关闭流try
        try{
            //分片下载
            //获取文件长度
            long fSize=file.length();
            //设置头
            response.setContentType("application/x-download");
            String fileName= URLEncoder.encode(file.getName(),"utf-8");
            //让前端弹出对话框下到哪里
            response.addHeader("Content-Disposition","attachment;filename="+filename);
            //告诉前端支持分片下载
            response.setHeader("Accept-Range","bytes");
            //设置下载文件的大小
            response.setHeader("fSize",String.valueOf(fSize));
            //告诉前端文件名字
            response.setHeader("fName", fileName);

            long pos=0,last=fSize-1,sum=0;
            if (null !=request.getHeader("Range")){
                response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);
                String numRange= request.getHeader("Range").replaceAll("bytes=","");
                String[] strRange = numRange.split("-");
                if(strRange.length==2){
                    pos=Long.parseLong(strRange[0].trim());
                    last=Long.parseLong(strRange[1].trim());
                    //如果结束字节超出文件大小
                    if(last>fSize-1){
                        last=fSize-1;
                    }
                } else {
                    pos=Long.parseLong(numRange.replaceAll("-","").trim());
                }
            }
            long rangeLenght = last - pos + 1;
            String contentRange=new StringBuffer("bytes ").append(pos).append("-").append(last).append("/").append(fSize).toString();
            response.setHeader("Content-Range",contentRange);
            response.setHeader("Cotent-Lenght",String.valueOf(rangeLenght));

            os=new BufferedOutputStream(response.getOutputStream());
            is=new BufferedInputStream(new FileInputStream(file));
            is.skip(pos);
            byte[] buffer=new byte[1024];
            int lenght=0;
            while (sum<rangeLenght){
                lenght=is.read(buffer,0,((rangeLenght-sum)<=buffer.length?((int)(rangeLenght-sum)):buffer.length));
                sum=sum+lenght;
                os.write(buffer,0,lenght);
            }
        }finally {
            if (is!=null){
                is.close();
            }
            if (os!=null){
                os.close();
            }
        }

    }

}

导入依赖

<dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>

访问路径:localhost:8080/upload3/downLoadFile/下载的东西

传递的参数:下载的文件名

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot 文件下载是指从 Web 应用程序中下载文件的过程。 要在 Spring Boot 中实现文件下载功能,你需要做以下几件事: 1. 在 Spring Boot 项目中添加对 Servlet 和 Apache Commons FileUpload 的依赖。 2. 创建一个控制器方法来处理文件下载请求。 3. 使用 `ResponseEntity` 对象将文件内容和相关信息作为响应返回给客户端。 4. 在客户端的浏览器中提供一个链接,用户点击该链接时发出文件下载请求。 以下是一个示例代码,它展示了如何在 Spring Boot 中实现文件下载功能: ```java @GetMapping("/download") public ResponseEntity<InputStreamResource> downloadFile(@RequestParam("fileName") String fileName) throws IOException { MediaType mediaType = MediaTypeUtils.getMediaTypeForFileName(this.servletContext, fileName); System.out.println("fileName: " + fileName); System.out.println("mediaType: " + mediaType); File file = new File(UPLOADED_FOLDER + fileName); InputStreamResource resource = new InputStreamResource(new FileInputStream(file)); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + file.getName()) .contentType(mediaType) .contentLength(file.length()) .body(resource); } ``` 在这段代码中,我们使用 `ResponseEntity` 对象来返回文件内容和相关信息给客户端,并使用 `InputStreamResource` 将文件转换为输入流。 我希望这对你有帮助! ### 回答2: Spring Boot是一个快速构建基于Spring的应用程序的框架。文件下载是Web应用程序中常见的功能之一,Spring Boot提供了简单且灵活的方式来实现文件下载。 首先,我们需要在Spring Boot项目中添加文件下载的依赖。在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> ``` 然后,在Controller层中创建一个用于处理文件下载的接口。可以使用`@RequestMapping`或`@GetMapping`注解来指定接口的URL路径,并使用`@ResponseBody`注解将方法的返回值直接作为响应体返回给客户端。 ```java @Controller public class FileDownloadController { @GetMapping("/download") @ResponseBody public ResponseEntity<Resource> downloadFile() { // 从本地或网络中获取要下载文件 File file = new File("path/to/file"); // 创建资源对象 Resource resource = new UrlResource(file.toURI()); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"") .body(resource); } } ``` 以上代码中,我们首先通过`File`类从指定路径获取要下载文件,然后将文件封装为`Resource`对象。在返回值中,我们使用`ResponseEntity`来构建响应体,并使用`Content-Disposition`头部指定下载文件的名称。最后,使用`.body()`方法将文件资源作为响应体返回给客户端。 最后,我们可以通过浏览器或其他工具发送GET请求访问`/download`接口,即可实现文件下载。 以上就是使用Spring Boot实现文件下载的简单示例。在实际应用中,还可以进行一些扩展,例如添加权限验证、处理异常等。 ### 回答3: Spring Boot 是一个开发框架,它是用于创建独立的、基于Spring的应用程序的工具。它提供了许多方便的功能和组件,可以帮助我们快速构建和部署应用程序。 在Spring Boot中,实现文件下载非常简单。我们可以使用Servlet的OutputStream将文件写入响应体,然后将响应发送给客户端。 首先,我们需要创建一个@Controller或@RestController类来处理文件下载的请求。 在该类中,我们需要定义一个处理文件下载请求的方法。这个方法可以使用@RequestParam注解来接收客户端传递的文件名参数。 接下来,我们可以使用Java的File类来读取文件。在读取文件时,我们可以使用InputStream来读取文件的内容。 然后,我们可以使用Spring的MultipartFile类将文件写入响应体。我们可以使用response.getOutputStream()获取响应的输出流,并使用response.setHeader()方法设置响应头,以告诉浏览器该文件将被下载。 最后,我们需要使用response.flush()方法刷新响应,以确保文件被完整写入响应体。 下面是一个简单的示例代码: ```java @Controller public class FileDownloadController { @GetMapping("/download") public void downloadFile(@RequestParam("filename") String filename, HttpServletResponse response) throws IOException { // 读取文件 File file = new File(filename); InputStream inputStream = new FileInputStream(file); // 设置响应头 response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=" + file.getName()); // 写入响应体 OutputStream outputStream = response.getOutputStream(); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } // 刷新响应 outputStream.flush(); // 关闭流 outputStream.close(); inputStream.close(); } } ``` 以上就是使用Spring Boot实现文件下载的简单介绍。使用这种方式,我们可以轻松地处理文件下载的请求,并将文件发送给客户端。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值