# 文件下载说明

文件下载核心:一个流,两个头

  • 输出流response.getOutputStream()
  • Content-Disposition
  • Content-Type

# 本地文件下载参考示例

使用缓冲流返回

/**
* 下载文件
* @param path
* @param fileName
* @param response
*/
public static void downLoad(String path, String fileName,HttpServletResponse response) {
	// 服务器保存的文件地址,即你要下载的文件地址(全路径)
	File file = new File(path);
	InputStream inputStream = null;
	OutputStream outputStream = null;
	try {
		inputStream = new BufferedInputStream(new FileInputStream(file));
		byte[] buffer = new byte[inputStream.available()];
		inputStream.read(buffer);
		response.reset();
		response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		response.addHeader("Content-Length", "" + file.length());
		response.setContentType("application/octet-stream");
		outputStream = new BufferedOutputStream(response.getOutputStream());
		outputStream.write(buffer);
		outputStream.flush();
	}
	catch (IOException e) {
		e.printStackTrace();
		throw new GGException(e.getMessage());
	}
	finally {
		try {
			if (outputStream != null) {
				outputStream.close();
			}
			if (inputStream != null) {
				inputStream.close();
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
}
public HttpServletResponse download(String path, HttpServletResponse response) {

    try {
        // path是指欲下载的文件的路径。
        File file = new File(path);
        // 取得文件名。
        String filename = file.getName();
        // 取得文件的后缀名。
        String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase();
        // 以流的形式下载文件。
        InputStream fis = new BufferedInputStream(new FileInputStream(path));
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        // 清空response
        response.reset();
        // 设置response的Header
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
        response.addHeader("Content-Length", "" + file.length());
        OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        toClient.write(buffer);
        toClient.flush();
        toClient.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    }
    return response;
}


public void downloadLocal(HttpServletResponse response) throws FileNotFoundException {

    // 下载本地文件
    String fileName = "Operator.doc".toString(); // 文件的默认保存名
    // 读到流中
    InputStream inStream = new FileInputStream("c:/Operator.doc");// 文件的存放路径
    // 设置输出的格式
    response.reset();
    response.setContentType("bin");
    response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
    // 循环取出流中的数据
    byte[] b = new byte[100];
    int len;
    try {
        while ((len = inStream.read(b)) > 0)
            response.getOutputStream().write(b, 0, len);
        inStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

使用commons-io工具

/**
     * 下载文件
     * @param path
     * @param response
     */
public static void nativeDownload(String path, HttpServletResponse response) {
    // 服务器保存的文件地址,即你要下载的文件地址(全路径)
    File file = new File(path);
    try {
        //2、两个头
        //获取Content-type
        Optional<MediaType> mediaType = MediaTypeFactory.getMediaType(path);
        String contentType = mediaType.orElse(MediaType.APPLICATION_OCTET_STREAM).toString();
        response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
        response.setContentType(contentType);
        //1、一个流
        InputStream is = Files.newInputStream(file.toPath());
        ServletOutputStream os = response.getOutputStream();
        IOUtils.copy(is,os);
        IOUtils.closeQuietly(is);
    } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException(e.getMessage());
    }
}

网络收集

1、使用HttpServletResponse输出流实现

@GetMapping("/download")
public void bianPdfDownload(HttpServletRequest request, HttpServletResponse response) throws Exception {

    // 请求类型、请求参数、请求头 根据需求制定即可
    // 获取到需要下载的文件
    // 如何生成文件,根据实际业务需求改造即可
    String outputFilePath = "/data/file-store-temp/2023年05月13日分析报告.pdf";
    log.debug("待下载文件:{}", outputFilePath);
    // 下载文件
    // 设置响应的内容类型,让浏览器知道下载的是一个文件
    ServletContext context = request.getServletContext();
    // get MIME type of the file
    String mimeType = context.getMimeType(outputFilePath);
    if (mimeType == null) {
        // set to binary type if MIME mapping not found
        mimeType = "application/octet-stream";
        log.debug("context getMimeType is null");
    }
    log.debug("MIME type: " + mimeType);
    // 设置响应头信息,告诉浏览器文件的名称和长度
    // set content attributes for the response
    response.setContentType(mimeType);
    response.setContentLength((int) file.length());
    // 设置编码
    response.setCharacterEncoding("utf-8");
    // 设置请求头参数以及下载的文件名称,中文名称转义防止乱码
    String headerValue = String.format("attachment; filename=%s",
                                       UriUtils.encode(fileName1, StandardCharsets.UTF_8));

    response.setHeader(HttpHeaders.CONTENT_DISPOSITION, headerValue);
    // Copy the stream to the response's output stream.
    try {
        InputStream myStream = new FileInputStream(outputFilePath);
        IOUtils.copy(myStream, response.getOutputStream());
        response.flushBuffer();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

2、使用ResponseEntity实现

import org.springframework.web.util.UriUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

@GetMapping("/download")
public ResponseEntity<Resource> downloadFile() throws Exception {

    // 请求类型、请求参数、请求头 根据需求制定即可
    // 获取到需要下载的文件
    // 如何生成文件,根据实际业务需求改造即可
    String fileName = "2023年05月13日分析报告.pdf";
    String outputFilePath = "/data/file-store-temp/" + fileName;
    log.debug("待下载文件:{}", outputFilePath);
    Path path = Paths.get(outputFilePath);
    Resource resource = null;
    try {
        resource = new UrlResource(path.toUri());
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    // 设置请求头参数以及下载的文件名称,中文名称转义防止乱码
    HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" +
                UriUtils.encode(fileName, StandardCharsets.UTF_8));
    // 
    headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
    headers.add("Pragma", "no-cache");
    headers.add("Expires", "0");
    // 返回响应实体,包含文件内容和响应头
    return ResponseEntity.ok()
        .headers(headers)
        .contentLength(resource.contentLength())
        .contentType(MediaType.parseMediaType("application/octet-stream"))
        .body(resource);
}

# 在线打开的方式

public void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception {

    File f = new File(filePath);
    if (!f.exists()) {
        response.sendError(404, "File not found!");
        return;
    }
    BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
    byte[] buf = new byte[1024];
    int len = 0;
    response.reset(); // 非常重要
    if (isOnLine) { // 在线打开方式
        URL u = new URL("file:///" + filePath);
        response.setContentType(u.openConnection().getContentType());
        response.setHeader("Content-Disposition", "inline; filename=" + f.getName());
        // 文件名应该编码成UTF-8
    } else { // 纯下载方式
        response.setContentType("application/x-msdownload");
        response.setHeader("Content-Disposition", "attachment; filename=" + f.getName());
    }
    OutputStream out = response.getOutputStream();
    while ((len = br.read(buf)) > 0)
        out.write(buf, 0, len);
    br.close();
    out.close();
}

# Excel文件导出

    public void downLoadXlsByJxl(HttpServletResponse response){
        try {
//            创建一个工作薄
            ServletOutputStream outputStream = response.getOutputStream();
            WritableWorkbook workbook = jxl.Workbook.createWorkbook(outputStream);
//            创建一个工作表
            WritableSheet sheet = workbook.createSheet("一个JXL入门", 0);
//            设置列宽
            sheet.setColumnView(0,5);//参数一:列索引,参数二:一个字母标准宽度
            sheet.setColumnView(1,8);
            sheet.setColumnView(2,15);
            sheet.setColumnView(3,15);
            sheet.setColumnView(4,30);
//            处理标题
            String[] titles = new String[]{"编号","姓名","手机号","入职日期","现住址"};
            Label label = null;
            for (int i = 0; i < titles.length; i++) {
                label = new Label(i,0,titles[i]);
                sheet.addCell(label);
            }
//            处理导出的内容
            List<User> userList = this.findAll();
            int rowIndex = 1;
            for (User user : userList) {
                label = new Label(0,rowIndex,user.getId().toString());
                sheet.addCell(label);
                label = new Label(1,rowIndex,user.getUserName());
                sheet.addCell(label);
                label = new Label(2,rowIndex,user.getPhone());
                sheet.addCell(label);
                label = new Label(3,rowIndex,simpleDateFormat.format(user.getHireDate()));
                sheet.addCell(label);
                label = new Label(4,rowIndex,user.getAddress());
                sheet.addCell(label);
                rowIndex++;
            }

            //            导出的文件名称
            String filename="一个JXL入门.xls";
//            设置文件的打开方式和mime类型
            response.setHeader( "Content-Disposition", "attachment;filename="  + new String(filename.getBytes(),"ISO8859-1"));
            response.setContentType("application/vnd.ms-excel");
//            导出
            workbook.write();
//            关闭资源
            workbook.close();
            outputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

# URL下载

网络收集

public void download2(HttpServletResponse response, String bucketName, String minFileName) {
    InputStream fileInputStream = null;
    //获取文件后缀
    String fileType = minFileName.substring(minFileName.indexOf(".") + 1);
    try {
        //mp4视频
        if("mp4".equals(fileType)){
            //我这里的访问路径是http开头的(minio文件服务器)
            URL url=new URL(“文件路径”);
            URLConnection connection = url.openConnection();
            fileInputStream = connection.getInputStream();
            response.addHeader("Content-Type","video/mp4;charset=UTF-8");
        }else {
            //我这里是minio文件服务器获取流
            fileInputStream = client.getObject(GetObjectArgs.builder()
                                               .bucket(bucketName)
                                               .object(minFileName).build());
            if ("jpg".equals(fileType) || "png".equals(fileType) || "gif".equals(fileType)) {
                response.setContentType("image/" + fileType);
            } else {
                //如果是其他方式进行下载操作
                String filename = URLEncoder.encode(minFileName.substring(minFileName.indexOf("-") + 1),"UTF-8");
                response.setHeader("Content-Disposition", "attachment;filename=" + filename);
                response.setContentType("application/force-download");
                response.setCharacterEncoding("UTF-8");
            }
        }
        //流转换
        IOUtils.copy(fileInputStream, response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 关闭流
        if (Objects.nonNull(fileInputStream)) {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
public void downloadNet(HttpServletResponse response) throws MalformedURLException {

    // 下载网络文件
    int bytesum = 0;
    int byteread = 0;
    URL url = new URL("windine.blogdriver.com/logo.gif");
    try {
        URLConnection conn = url.openConnection();
        InputStream inStream = conn.getInputStream();
        FileOutputStream fs = new FileOutputStream("c:/abc.gif");
        byte[] buffer = new byte[1204];
        int length;
        while ((byteread = inStream.read(buffer)) != -1) {
            bytesum += byteread;
            System.out.println(bytesum);
            fs.write(buffer, 0, byteread);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
public void downLoadFile(HttpServletResponse response, String httpUrl) {
    ServletOutputStream out = null;
    try {
        //与服务器建立连接
        URL url = new URL(httpUrl);
        URLConnection conn = url.openConnection();
        InputStream inputStream = conn.getInputStream();
        try {
            //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型
            response.setContentType("multipart/form-data");
        } catch (Exception e){
            e.printStackTrace();
        }
        out = response.getOutputStream();
        // 读取文件流
        int len = 0;
        byte[] buffer = new byte[1024 * 10];
        while ((len = inputStream.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.flush();
        out.close();
        inputStream.close();
    } catch (Exception e){
        e.printStackTrace();
    }
}

# URL打包下载

网络收集 使用了压缩流

public void download(HttpServletRequest request, HttpServletResponse response){

    try {
        String downloadFilename = "中文.zip";//文件的名称
        downloadFilename = URLEncoder.encode(downloadFilename, "UTF-8");//转换中文否则可能会产生乱码
        response.setContentType("application/octet-stream");// 指明response的返回对象是文件流 
        response.setHeader("Content-Disposition", "attachment;filename=" + downloadFilename);// 设置在下载框默认显示的文件名
        ZipOutputStream zos = new ZipOutputStream(response.getOutputStream());
        String[] files = new String[]{"http://xxxx/xx.jpg","http://xxx/xx.jpg"};
        for (int i=0;i<files.length;i++) {
            URL url = new URL(files[i]);
            zos.putNextEntry(new ZipEntry(i+".jpg"));
            //FileInputStream fis = new FileInputStream(new File(files[i]));  
            InputStream fis = url.openConnection().getInputStream();   
            byte[] buffer = new byte[1024];     
            int r = 0;     
            while ((r = fis.read(buffer)) != -1) {     
                zos.write(buffer, 0, r);     
            }     
            fis.close();   
        }  
        zos.flush();     
        zos.close();
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  
}

# URL保存到本地

public String httpDownload(String httpUrl){
    try {
        URL url = new URL(httpUrl) ;
        //filePath文件地址,fileName文件名
        File file = new File(filePath, fileName);
        FileUtils.copyURLToFile(url,file);
    } catch (IOException e) {
        logger.info("用印文件下载失败:{}",e.getMessage());
        return null;
    }
    //文件地址
    return basePath + "/" + fileName;
}

# URL流量返回

public void httpDownload(String httpUrl,HttpServletResponse response)throws IOException{
        URL url = new URL(httpUrl) ;
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection() ;
        urlConnection.connect() ;
        OutputStream outputStream = response.getOutputStream();
        InputStream inputStream = urlConnection.getInputStream() ;
        IOUtils.copy(inputStream,outputStream);
        inputStream.close();
        response.flushBuffer();
        outputStream.close();
}

# 将文件转换成base64

/**
     * 将文件转为base64
     */
public static String getBase64FromFile(File file) throws IOException {
    FileInputStream in = null;
    ByteArrayOutputStream out = null;
    try {
        in = new FileInputStream(file);
        out = new ByteArrayOutputStream();
        int read = 0;
        byte[] buffer = new byte[1024];
        while ((read = in.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, read);
        }

        return Base64.getEncoder().encodeToString(out.toByteArray());
    } catch (IOException e) {
        throw e;
    } finally {
        if (in != null) {
            in.close();
        }
        if (out != null){
            out.close();
        }
    }
}


# 将MultipartFile转换为File

/**
     * 将MultipartFile转换为File
     */
public static File MultipartFileToFile(MultipartFile multiFile) throws IOException {
    String fileName = multiFile.getOriginalFilename();
    String prefix = fileName.substring(fileName.lastIndexOf("."));
    InputStream in = null;
    OutputStream out = null;
    try {
        File file = File.createTempFile(fileName, prefix);
        out = new FileOutputStream(file);
        in = multiFile.getInputStream();
        int read = 0;
        byte[] buffer = new byte[1024];
        while ((read = in.read(buffer, 0, 1024)) != -1) {
            out.write(buffer, 0, read);
        }

        return file;
    } catch (Exception e) {
        throw e;
    }finally {
        if (in != null){
            in.close();
        }
        if (out != null){
            out.close();
        }
    }
}

public void download2(HttpServletResponse response, String bucketName, String minFileName) {
    InputStream fileInputStream = null;
    //获取文件后缀
    String fileType = minFileName.substring(minFileName.indexOf(".") + 1);
    try {
        //mp4视频
        if("mp4".equals(fileType)){
            //我这里的访问路径是http开头的(minio文件服务器)
            URL url=new URL(“文件路径”);
            URLConnection connection = url.openConnection();
            fileInputStream = connection.getInputStream();
            response.addHeader("Content-Type","video/mp4;charset=UTF-8");
        }else {
            //我这里是minio文件服务器获取流
            fileInputStream = client.getObject(GetObjectArgs.builder()
                                               .bucket(bucketName)
                                               .object(minFileName).build());
            if ("jpg".equals(fileType) || "png".equals(fileType) || "gif".equals(fileType)) {
                response.setContentType("image/" + fileType);
            } else {
                //如果是其他方式进行下载操作
                String filename = URLEncoder.encode(minFileName.substring(minFileName.indexOf("-") + 1),"UTF-8");
                response.setHeader("Content-Disposition", "attachment;filename=" + filename);
                response.setContentType("application/force-download");
                response.setCharacterEncoding("UTF-8");
            }
        }
        //流转换
        IOUtils.copy(fileInputStream, response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 关闭流
        if (Objects.nonNull(fileInputStream)) {
            try {
                fileInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

esponse.setContentType()参数有哪些,该博主地址有统计https://blog.csdn.net/weixin_41926301/article/details/83827032

@ApiOperation("下载")
@GetMapping("/download/{id}")
@ApiImplicitParams({
    @ApiImplicitParam(name="id",value = "文件id",required = true)
})
public void download(@PathVariable @NotBlank(message = "id不能为空") String id, HttpServletResponse response) throws JsonProcessingException {
    FileInfo fileInfo = voiceFileService.getById(id);
    if (fileInfo == null) {
        WebUtils.responseResult(response,ResponseBean.fail("未找到上传文件信息"));
        return;
    }
    String contentType = fileInfo.getContentType();
    response.addHeader(HttpHeaders.CONTENT_DISPOSITION,"attachment; filename*=UTF-8''" +
                       UriUtils.encode(fileInfo.getOriginalFilename(), StandardCharsets.UTF_8)
                      );
    response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
    response.setContentType(contentType);
    try {
        fileStorageService.download(fileInfo).outputStream(response.getOutputStream());
    } catch (IOException e) {
        e.printStackTrace();
    }
}
package com.jysp.voice.common.core.utils;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jydw.da.common.core.dataModel.common.vo.ResponseBean;
import lombok.extern.slf4j.Slf4j;
import org.xnio.Result;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@Slf4j
public class WebUtils {

    private static ObjectMapper mapper =  new ObjectMapper();
    /**
     * 将字符串渲染到客户端
     *
     * @param response 渲染对象
     * @param string   待渲染的字符串
     * @return null
     */
    public static String renderString(HttpServletResponse response, String string) {
        try {
            response.setStatus(200);
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    public static void responseResult(HttpServletResponse response, ResponseBean<?> result) {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Type", "application/json;charset=UTF-8");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setStatus(HttpServletResponse.SC_OK);
        PrintWriter writer = null;
        try {
            // JSON.toJSONString(result)要获取完整的json字符串,每一个字段都要有set和get方法,不然会缺少某个字段
            writer = response.getWriter();
            //            writer.write(JSON.toJSONString(result));
            writer.write(mapper.writeValueAsString(result));
            writer.flush();
        } catch (IOException ex) {
            log.error(ex.getMessage());
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
}

# httpClient转发下载

调用第三方文件下载接口,通过HttpClient的方式进行调用,需要从HttpResponse解析出参数,并读取流变成文件下载 调用部分

/**
*   调用GET请求  文件下载
*
*/
public static void fileDownload(String url,String cookie) throws Exception {
	HttpClient client = null;
	HttpGet get = new HttpGet(url);
	get.setHeader("Content-Type", "application/x-www-form-urlencoded");
	get.setHeader("Cookie", cookie);
	try {
		RequestConfig.Builder customReqConf = RequestConfig.custom();
		customReqConf.setConnectTimeout(DEFAULT_CONNECTION_TIME_OUT.intValue());
		customReqConf.setSocketTimeout(DEFAULT_CONNECTION_TIME_OUT.intValue());
		get.setConfig(customReqConf.build());
		HttpResponse res = null;
		client = createSSLInsecureClient();
		res = client.execute(get);
		HttpEntity entity = res.getEntity();
		InputStream inputStream = entity.getContent();
        
        //这里的流文件亦可以直接转换成 MutiParFile文件 ,
        MultipartFile multipartFile = new MockMultipartFile("temp.jpg","temp.jpg","", inputStream);
        
		String rootPath ="C:\\Users\\Administrator\\Desktop\\";

		String suffix = ".png";
		Long index = System.currentTimeMillis();

		String fileName = rootPath + index + suffix;
		writeToLocal(fileName,inputStream);

		
	} finally {
		get.releaseConnection();
		if ((url.startsWith("https")) && (client != null) && ((client instanceof CloseableHttpClient))) {
			((CloseableHttpClient) client).close();
		}
	}
}

	/**
	 * 文件下载
	 * @param destination  下载路径
	 * @param input
	 * @throws IOException
	 */
public static void writeToLocal(String destination, InputStream input)
			throws IOException {
	int index;
	byte[] bytes = new byte[1024];
	FileOutputStream downloadFile = new FileOutputStream(destination);
	while ((index = input.read(bytes)) != -1) {
		downloadFile.write(bytes, 0, index);
		downloadFile.flush();
	}
	input.close();
	downloadFile.close();

	}

# 多个文件压缩并批量下载

private void getZip(List<String> files,HttpServletResponse response){

    response.setContentType("application/x-msdownload");
    response.setHeader("Content-Disposition","attachment;filename=人脸图像.zip");

    String rootPath = configuration.getRootpath();
    if(CollectionUtils.isEmpty(files)){

        log.error(rootPath + "路径不存");
    }
    String zipName ="人脸图像.zip";
    String zipPath = rootPath + zipName;
    BufferedInputStream bis =null;
    try {
        //ZipOutputStream zipOutput = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipPath)));
        ZipOutputStream zipOutput = new ZipOutputStream(response.getOutputStream());
        for(String str :  files) {
            File  file = new File(rootPath ,str);
            if(!file.exists()){
                log.error("文件被删除");
                continue;
            }
            ZipEntry zEntry = new ZipEntry(file.getName());
            zipOutput.putNextEntry(zEntry);
            bis = new BufferedInputStream(new FileInputStream(file));
            byte[] buffer = new byte[1024];
            int read = 0;
            while((read = bis.read(buffer)) != -1){
                zipOutput.write(buffer, 0, read);
            }
        }
        zipOutput.finish();
        bis.close();
        zipOutput.close();

    } catch (Exception e) {
        e.printStackTrace();
        log.error(e.getMessage());
    }
}

# 第三方接口,文件流转发

package com.example.demo;

import cn.hutool.core.util.IdUtil;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

import static org.apache.catalina.manager.Constants.CHARSET;

@RestController
@RequestMapping("file")
public class TestController {

    /**
     * 前端下载文件
     * @param response
     * @throws UnsupportedEncodingException
     */
    @GetMapping(value = "/test1")
    public void test(HttpServletResponse response) throws UnsupportedEncodingException {
        // 设置编码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("test.pdf", "UTF-8"));
        String path = "D://test.pdf";
        try {
            FileInputStream in = new FileInputStream(new File(path));
            FileCopyUtils.copy(in, response.getOutputStream());
        } catch (FileNotFoundException e) {
            System.out.println("文件不存在");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 前端预览文件
     * @param response
     * @throws IOException
     */
    @RequestMapping("download")
    public void download(HttpServletResponse response) throws IOException {
        String filePath = "D:\\test.pdf";
        System.out.println("filePath:" + filePath);
        File f = new File(filePath);
        if (!f.exists()) {
            response.sendError(404, "File not found!");
            return;
        }
        BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
        byte[] bs = new byte[1024];
        int len = 0;
        response.reset(); // 非常重要
        URL u = new URL("file:///" + filePath);
        String contentType = u.openConnection().getContentType();
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "inline;filename="
                + "test.pdf");
        // 文件名应该编码成utf-8,注意:使用时,我们可忽略这句
        OutputStream out = response.getOutputStream();
        while ((len = br.read(bs)) > 0) {
            out.write(bs, 0, len);
        }
        out.flush();
        out.close();
        br.close();
    }

    /**
     * 调用第三方流接口, 将文件保存到本地、读取本地文件返回前端预览
     * @param response
     * @throws IOException
     */
    @RequestMapping("test2")
    public void test2(HttpServletResponse response) throws IOException {
        HttpURLConnection urlConnection = null;
        FileOutputStream fileOutputStream;
        InputStream inputStream;
        String fileName = IdUtil.nanoId();
        try {
            URL url = new URL("http://localhost:8080/file/download");
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setConnectTimeout(20000);
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
            urlConnection.connect();

            File file = new File("D://"+fileName+".pdf");
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            inputStream = urlConnection.getInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            fileOutputStream = new FileOutputStream("D://"+fileName+".pdf");
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);

            byte[] buf = new byte[4096];
            int length = bufferedInputStream.read(buf);
            while (-1 != length) {
                bufferedOutputStream.write(buf, 0, length);
                length = bufferedInputStream.read(buf);
            }
            bufferedInputStream.close();
            bufferedOutputStream.close();
        } catch (Exception e) {
            System.out.println("getFile error: " + e);
        } finally {
            if (null != urlConnection) {
                urlConnection.disconnect();
            }
        }
        String filePath = "D://"+fileName+".pdf";
        File f = new File("D://"+fileName+".pdf");
        if (!f.exists()) {
            response.sendError(404, "File not found!");
            return;
        }
        BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
        byte[] bs = new byte[1024];
        int len = 0;
        response.reset(); // 非常重要
        URL u = new URL("file:///" + filePath);
        String contentType = u.openConnection().getContentType();
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "inline;filename="
                + fileName + ".pdf");
        // 文件名应该编码成utf-8,注意:使用时,我们可忽略这句
        OutputStream out = response.getOutputStream();
        while ((len = br.read(bs)) > 0) {
            out.write(bs, 0, len);
        }
        out.flush();
        out.close();
        br.close();
    }

    /**
     * 调用第三方流接口, 将文件流返回前端预览
     * @param request
     * @param response
     */
    @RequestMapping("test3")
    public void test3(HttpServletRequest request, HttpServletResponse response) {
        HttpURLConnection urlConnection = null;
        InputStream inputStream;
        try {
            URL url = new URL("http://localhost:8080/file/download");
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("POST");
            urlConnection.setConnectTimeout(20000);
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.setUseCaches(false);
            urlConnection.setRequestProperty("Content-Type", "application/json; charset=" + CHARSET);
            urlConnection.connect();
            inputStream = urlConnection.getInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            byte[] buf = new byte[4096];
            int length = bufferedInputStream.read(buf);
            ServletOutputStream out = response.getOutputStream();
            while (-1 != length) {
                out.write(buf, 0,length);
                length = bufferedInputStream.read(buf);
            }
            out.flush();
            out.close();
            bufferedInputStream.close();
        } catch (Exception e) {
            System.out.println("getFile error: " + e);
        } finally {
            if (null != urlConnection) {
                urlConnection.disconnect();
            }
        }
    }
}
更新时间: 2023年12月12日星期二下午3点28分