首先定义Servlet接口接收课程ID和文件名参数,通过安全校验防止路径穿越,再定位文件并设置响应头,最后输出文件流实现下载。

实现课程资料下载功能,核心是通过Java构建一个服务端程序,接收客户端请求,定位对应课程的文件资源,并将其输出给用户。整个过程涉及文件读取、HTTP响应处理和路径安全管理。以下是具体实现步骤和代码示例。
1. 定义下载接口
使用Java的Servlet技术处理HTTP请求。用户通过URL传递课程ID或文件名,服务器根据参数查找并返回对应文件。
示例URL:/download?courseId=101&file=lecture1.pdf
2. 实现文件查找与安全校验
确保用户只能访问允许下载的目录,防止路径穿越攻击(如 ../../../etc/passwd)。
立即学习“Java免费学习笔记(深入)”;
- 将所有课程资料放在指定目录,例如:/data/course_files/- 使用白名单机制限制可访问的子目录
- 对文件名进行规范化处理,禁止包含 "../" 等非法字符
3. 编写Servlet处理下载逻辑
以下是一个简化的Java Servlet示例:
一套面向小企业用户的企业网站程序!功能简单,操作简单。实现了小企业网站的很多实用的功能,如文章新闻模块、图片展示、产品列表以及小型的下载功能,还同时增加了邮件订阅等相应模块。公告,友情链接等这些通用功能本程序也同样都集成了!同时本程序引入了模块功能,只要在系统默认模板上创建模块,可以在任何一个语言环境(或任意风格)的适当位置进行使用!
@WebServlet("/download")
public class CourseDownloadServlet extends HttpServlet {
private static final String BASE_DIR = "/data/course_files/";
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String courseId = request.getParameter("courseId");
String fileName = request.getParameter("file");
// 基本校验
if (courseId == null || fileName == null || fileName.contains("..")) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// 构建安全路径
Path basePath = Paths.get(BASE_DIR);
Path requestedFile = basePath.resolve(courseId).resolve(fileName).normalize();
// 确保文件在允许目录内
if (!requestedFile.startsWith(basePath)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
if (!Files.exists(requestedFile)) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 设置响应头
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" +
URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setContentLengthLong(Files.size(requestedFile));
// 输出文件流
try (InputStream in = Files.newInputStream(requestedFile)) {
StreamUtils.copy(in, response.getOutputStream());
}
}
}
4. 处理中文文件名与编码
浏览器对中文文件名支持不一,建议使用URLEncoder.encode()并配合ISO-8859-1兼容模式。
例如:filename*=UTF-8''%E8%AE%B2%E4%B9%89.pdf 可提升兼容性。
基本上就这些。只要路径控制得当,流式输出稳定,Java实现文件下载并不复杂但容易忽略安全细节。









