Skip to content

Java Web文件下载实现详解

Published:  at  03:34 AM

文件下载案例(Servlet)

文件下载是 Java Web 开发中的常见需求,其本质是:
服务器以“附件”的形式将文件内容通过响应流返回给浏览器


一、实现思路概述

整体流程如下:

  1. 浏览器通过超链接向服务器发送请求,并携带文件名参数
  2. Servlet 接收请求,获取文件名
  3. 通过 ServletContext 获取文件在服务器中的真实路径
  4. 使用字节输入流读取文件内容
  5. 设置响应头(MIME 类型 + 下载方式)
  6. 将文件内容写入响应输出流,返回给浏览器

二、前端 HTML 页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>文件下载示例</title>
</head>
<body>

<!-- 通过超链接访问 Servlet,并携带要下载的文件名 -->
<a href="/DownloadTest/downloadServlet?filename=1.jpg">点击下载图片 1</a><br>
<a href="/DownloadTest/downloadServlet?filename=2.jpg">点击下载图片 2</a><br>
<a href="/DownloadTest/downloadServlet?filename=3.jpg">点击下载图片 3</a><br>

</body>
</html>

说明


三、Servlet 后端实现

import javax.servlet.ServletException;
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.FileInputStream;
import java.io.IOException;

@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // 1. 获取请求参数(文件名)
        String filename = request.getParameter("filename");

        // 2. 获取文件在服务器中的真实路径
        String realPath = this.getServletContext()
                .getRealPath("/img/" + filename);

        // 3. 使用字节输入流读取文件
        FileInputStream fis = new FileInputStream(realPath);

        // 4. 设置响应头 —— MIME 类型
        String mimeType = this.getServletContext().getMimeType(filename);
        response.setContentType(mimeType);

        // 5. 设置响应头 —— 下载方式(附件形式)
        response.setHeader(
                "Content-Disposition",
                "attachment;filename=" + filename
        );

        // 6. 将文件内容写入响应输出流
        ServletOutputStream sos = response.getOutputStream();
        byte[] buffer = new byte[8 * 1024];
        int len;

        while ((len = fis.read(buffer)) != -1) {
            sos.write(buffer, 0, len);
        }

        // 7. 释放资源
        fis.close();
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // GET 请求统一交由 POST 处理
        this.doPost(request, response);
    }
}

四、关键点解析

1. 文件真实路径获取

getServletContext().getRealPath("/img/" + filename);

2. MIME 类型设置

String mimeType = getServletContext().getMimeType(filename);
response.setContentType(mimeType);

3. Content-Disposition 响应头

response.setHeader(
    "Content-Disposition",
    "attachment;filename=" + filename
);

作用:


4. 字节流传输文件


五、常见问题与优化建议

1. 中文文件名乱码问题

在实际项目中,中文文件名需要进行编码处理,例如:

filename = URLEncoder.encode(filename, "UTF-8");

2. 大文件下载


3. 安全性问题


Suggest Changes

Previous Post
会话技术与Cookie在客户端的应用
Next Post
ServletContext对象的功能与使用方法