Servlet 下载文件

// 文件路径 D:\ApacheServer\web_java\HelloWorld\src\com\test\TestServletDownload.java
package com.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

public class TestServletDownload {

    public void testfun(HttpServletResponse response){
        // 最好放在 response 所有输出之前调用,并且执行后避免再向浏览器发送其他输出流
        try{
            // 要下载的文件名
            String fileName = "00125943U-0.jpg";
            // 文件下载到客户端时文件名
            String downName = "download.jpg";
            
            // 获取项目运行根目录
            // Thread.currentThread().getContextClassLoader().getResource("") 获取项目运行实际 classes 目录 这里为 file:/D:/ApacheServer/web_java/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/HelloWorld/WEB-INF/classes/
            // 参数 "../../" 为取向上两级目录,这里为 file:/D:/ApacheServer/web_java/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/HelloWorld/
            // .toString().substring(6) 消除返回路径中的 file:/ 字符串,这里返回路径为 D:/ApacheServer/web_java/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/HelloWorld/
            String appBase = Thread.currentThread().getContextClassLoader().getResource("../../").toString().substring(6);
            
            // 获取文件的绝对路径,这里为 D:/ApacheServer/web_java/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/HelloWorld/upload/00125943U-0.jpg。File.separator 表示目录分割斜杠
            String fullFileName = appBase + "upload" + File.separator + fileName;
            
            // 获取文件 MIME 类型
            Path path = Paths.get(fullFileName);
            String mimeType = Files.probeContentType(path);
            
            // 设置文件 MIME 类型
            response.setContentType(mimeType);
            // 设置 Content-Disposition 响应报头,命名下载文件名称
            response.setHeader("Content-Disposition"," attachment;filename=" + downName);
            
            // 把文件读入到内存输入流中
            InputStream inputStream = new FileInputStream(fullFileName);
            // 创建输出流对象
            ServletOutputStream outputStream = response.getOutputStream();
            
            // 每次从输入流实际读取到的字节数
            int len = 0;
            // 定义一个字节数组,相当于缓存,数组长度为1024,即缓存大小为1024个字节
            byte[] cache = new byte[1024];
            // inputStream.read(cache)) 方法,从输入流中读取最多 cache 数组大小的字节,并将其存储在 cache 中。以整数形式返回实际读取的字节数,当文件读完时返回-1
            while((len = inputStream.read(cache)) != -1){
                // 每次把数组 cache 从 0 到 len 长度的内容输出到浏览器
                outputStream.write(cache, 0, len);
            }
            // 关闭流
            inputStream.close();
            outputStream.close();
        }catch(Exception exception) {
            // 处理 Class.forName 错误
            exception.printStackTrace();
        }
    }
}

 

posted @ 2019-09-08 15:42  风吹屁股凉冰冰  阅读(276)  评论(0编辑  收藏  举报