1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- package com.lovecoding.download;
- import org.apache.commons.io.IOUtils;
- import javax.servlet.ServletOutputStream;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.net.URLEncoder;
- @WebServlet("/downloadFile")
- public class DownloadAction extends HttpServlet {
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- /**
- * 正常的情况下 , 下载是不走Java逻辑代码的
- * 我们下载文件都交给 Tomcat, 文件是静态资源, Http 服务器 (Tomcat, Nginx ) 都能处理
- * 我们不用管 文件下载的事情
- * 特俗情况, 付费下载, 统计文件下载数量, 管控下载流量
- */
- /**
- * 一般情况下, 管控文件下载需要 Token !
- * 我们改需要 文件名
- * 我们使用 Java 管控文件下载 不一定非要 使用Java IO去处理文件
- * 301 跳转
- */
- /**
- * 一般情况下 我们需要把文件重命名, 或者加随即时间戳
- * 总之呢 尽可能不让用户猜到文件路径, 方案有很多
- * 用户使用的是一个映射文件名 "abc.pdf" => "202030517-abc.pdf"
- * 用户可能上传 攻击脚本
- */
- req.setCharacterEncoding("UTF-8");
- String fileName = req.getParameter("filename");
- if ( fileName == null || fileName.equals("") ) {
- resp.setContentType("text/html; charset=utf-8");
- resp.getWriter().print("请携带文件名访问");
- return ;
- }
- //取存储文件的文件夹路径
- String filePath = req.getServletContext().getRealPath("") + "uploads";
- //取拼接文件名
- String file = filePath + File.separator + fileName;
- //判断文件是否存在
- File file1 = new File(file);
- if ( !file1.exists() ) {
- resp.setContentType("text/html; charset=utf-8");
- resp.getWriter().print("<h1>文件不存在</h1>");
- return ;
- }
- //文件转文件流
- FileInputStream fileInputStream = new FileInputStream(file1);
- //取相应流
- ServletOutputStream outputStream = resp.getOutputStream();
- //向浏览器声明下载
- resp.addHeader("content-type", "application/octet-stream");
- //声明文件名
- String downloadFileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
- //header 使用 filename*=UTF-8'' 协议告诉浏览器后台文件编码是 UTF-8 可以解决中文文件名乱码问题
- resp.addHeader("content-disposition", "attachment; filename*=UTF-8''" + downloadFileName);
- //将文件的文件流和resp相应流合并输出
- IOUtils.copy( fileInputStream, outputStream );
- }
- }
|