<前文回顾>
<今日更新>
一、文件上传:从“拖拽”到“入库”
在 JavaWeb 开发里,文件上传就像“拖拽文件入库”,用户把文件“拖”到网页上,服务器把文件“拽”到硬盘里。文件上传的核心是 multipart/form-data 表单和 Servlet 的文件处理。
1. multipart/form-data 表单:文件的“快递单”
文件上传得用 multipart/form-data 表单,这种表单能把文件“打包”成二进制数据,发送给服务器。表单的 enctype 属性得设成 multipart/form-data,method 属性得设成 post。
HTML Code |
<form action="upload" method="post" enctype="multipart/form-data"> <input type="file" name="file"> <input type="submit" value="上传"> </form> |
2. Servlet 的文件处理:文件的“入库员”
文件上传到服务器后,Servlet 得把文件“入库”。Servlet 3.0 引入了 Part 接口,能方便地处理文件上传。
Java Code |
@WebServlet("/upload") @MultipartConfig public class UploadServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Part filePart = request.getPart("file"); String fileName = filePart.getSubmittedFileName(); filePart.write("/uploads/" + fileName); response.getWriter().write("文件上传成功!"); } } |
二、文件下载:从“出库”到“拖拽”
文件下载就像“出库文件拖拽”,服务器把文件“出库”,用户把文件“拖”到本地。文件下载的核心是 Servlet 的文件读取和响应头设置。
1. Servlet 的文件读取:文件的“出库员”
文件下载时,Servlet 得把文件“出库”。Servlet 得用 FileInputStream 读取文件,用 OutputStream 输出文件。
Java Code |
@WebServlet("/download") public class DownloadServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String fileName = request.getParameter("file"); File file = new File("/uploads/" + fileName); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\""); try (InputStream in = new FileInputStream(file); OutputStream out = response.getOutputStream()) { byte[] buffer = new byte[4096]; int length; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } } } } |
2. 响应头设置:文件的“快递单”
文件下载时,Servlet 得设置响应头,告诉浏览器“这是个文件,得下载”。响应头包括 Content-Type 和 Content-Disposition。
Java Code |
response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\""); |
三、文件管理的“历史”:从 Servlet 2.3 到 Servlet 4.0
文件管理从 Servlet 2.3 开始就有了,虽然现在 Servlet 4.0 已经“普及”了,但文件管理的“核心功能”依然没变。
1. Servlet 2.3:初代“文件管理员”
Servlet 2.3 在 2001 年发布,文件管理是它的“初代功能”。虽然功能简单,但已经能满足大部分开发需求了。
2. Servlet 3.0:引入 Part 接口
Servlet 3.0 在 2009 年发布,引入了 Part 接口[1],让文件上传更加方便。Part 接口的引入,让文件管理的“玩法”更加丰富。
Java Code |
Part filePart = request.getPart("file"); String fileName = filePart.getSubmittedFileName(); filePart.write("/uploads/" + fileName); |
3. Servlet 4.0:支持 HTTP/2
Servlet 4.0 在 2017 年发布,支持 HTTP/2[2],让文件管理的性能更上一层楼。HTTP/2 的引入,让文件管理的“玩法”更加高效。
四、文件管理的“骚操作”
1. 文件上传进度条
文件上传时,能用 Ajax 和 JavaScript 实现进度条,让用户知道“上传到哪了”。
Js Code |
function uploadFile() { var file = document.getElementById("file").files[0]; var formData = new FormData(); formData.append("file", file); var xhr = new XMLHttpRequest(); xhr.upload.onprogress = function(event) { var percent = (event.loaded / event.total) * 100; document.getElementById("progress").style.width = percent + "%"; }; xhr.open("POST", "upload", true); xhr.send(formData); } |
2. 文件下载限速
文件下载时,能用 Thread.sleep 限速,防止服务器“被拖垮”。
Java Code |
try (InputStream in = new FileInputStream(file); OutputStream out = response.getOutputStream()) { byte[] buffer = new byte[4096]; int length; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); Thread.sleep(10); // 限速 100KB/s } } |
3. 文件分片上传
大文件上传时,能用分片上传,防止服务器“吃不消”。
Js Code |
function uploadFile() { var file = document.getElementById("file").files[0]; var chunkSize = 1024 * 1024; // 1MB var chunks = Math.ceil(file.size / chunkSize); for (var i = 0; i < chunks; i++) { var start = i * chunkSize; var end = Math.min(start + chunkSize, file.size); var chunk = file.slice(start, end); var formData = new FormData(); formData.append("file", chunk); formData.append("chunk", i); formData.append("chunks", chunks); var xhr = new XMLHttpRequest(); xhr.open("POST", "upload", true); xhr.send(formData); } } |
五、Tomcat 的文件管理参数:从“默认值”到“调校”
Tomcat 的文件管理参数是它的“调校”,开发者能通过配置参数,调整文件管理的性能、行为啥的。Tomcat 的主要参数包括上传文件大小限制、上传文件临时目录啥的。
1. 上传文件大小限制:Tomcat 的“胃口”
上传文件大小限制是 Tomcat 的“胃口”,它决定了 Tomcat 能“吃”多大的文件。上传文件大小限制通常得根据硬盘空间、网络状况啥的“调校”。
XML Code |
<!-- web.xml 配置上传文件大小限制 --> <multipart-config> <max-file-size>10485760</max-file-size> <!-- 10MB --> <max-request-size>10485760</max-request-size> <!-- 10MB --> </multipart-config> |
2. 上传文件临时目录:Tomcat 的“临时仓库”
上传文件临时目录是 Tomcat 的“临时仓库”,它决定了 Tomcat 把上传文件“暂存”在哪。上传文件临时目录通常得根据硬盘空间、性能啥的“调校”。
XML Code |
<!-- server.xml 配置上传文件临时目录 --> <Context docBase="/path/to/webapps/myapp" tempDir="/path/to/temp" /> |
专有名词解释:
- Part 接口:Servlet 3.0 引入的接口,用于处理文件上传。
- HTTP/2:HTTP 协议的第二个主要版本,支持多路复用、头部压缩等特性。