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("