学习进度条
JavaWeb图片上传功能学习总结
今日学习时间:1小时
今日代码量:100行
今日博客:1篇(JavaWeb实现图片上传的三种方式)
一、核心知识点
- 前端表单配置
<!-- 必须设置enctype为multipart/form-data -->
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="imageFile" accept="image/*">
<input type="submit" value="上传">
</form>
- 后端Servlet处理(使用Apache Commons FileUpload)
// 添加Maven依赖
// <dependency>
// <groupId>commons-fileupload</groupId>
// <artifactId>commons-fileupload</artifactId>
// <version>1.4</version>
// </dependency>
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1. 检查请求是否包含文件
if (!ServletFileUpload.isMultipartContent(request)) {
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
return;
}
// 2. 配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(5 * 1024 * 1024); // 限制5MB
try {
// 3. 解析请求
List<FileItem> items = upload.parseRequest(request);
for (FileItem item : items) {
if (!item.isFormField()) { // 是文件字段
String fileName = new File(item.getName()).getName();
String savePath = getServletContext().getRealPath("/uploads");
// 4. 保存文件
File uploadDir = new File(savePath);
if (!uploadDir.exists()) uploadDir.mkdir();
File storeFile = new File(savePath + File.separator + fileName);
item.write(storeFile);
response.getWriter().print("上传成功: " + fileName);
}
}
} catch (Exception ex) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
}
- SpringMVC简化版(需配置MultipartResolver)
@Controller
public class ImageController {
@PostMapping("/upload")
public String handleUpload(@RequestParam("imageFile") MultipartFile file,
Model model) throws IOException {
if (!file.isEmpty()) {
String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
Path path = Paths.get("D:/uploads/" + fileName);
Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
model.addAttribute("msg", "上传成功: " + fileName);
}
return "result";
}
}
二、关键配置
- web.xml添加限制(可选)
<servlet>
<servlet-name>uploadServlet</servlet-name>
<servlet-class>com.example.UploadServlet</servlet-class>
<multipart-config>
<max-file-size>5242880</max-file-size> <!-- 5MB -->
<max-request-size>10485760</max-request-size> <!-- 10MB -->
</multipart-config>
</servlet>
- SpringBoot配置(application.properties)
# 单个文件最大
spring.servlet.multipart.max-file-size=5MB
# 总请求最大
spring.servlet.multipart.max-request-size=10MB
# 临时存储路径
spring.servlet.multipart.location=/tmp
三、安全注意事项
- 文件名校验
String fileExt = fileName.substring(fileName.lastIndexOf("."));
if(!Arrays.asList(".jpg", ".png").contains(fileExt.toLowerCase())) {
throw new IllegalArgumentException("只允许jpg/png格式");
}
- 防止目录穿越攻击
Path uploadPath = Paths.get("/safe/uploads").normalize();
Path filePath = uploadPath.resolve(fileName).normalize();
if(!filePath.startsWith(uploadPath)) {
throw new IOException("非法文件路径");
}
四、今日实践成果
- 实现了原生Servlet文件上传功能
- 完成了SpringMVC版本的上传接口
- 添加了基础的文件类型校验
- 测试了不同尺寸图片的上传(<5MB成功,>5MB失败)
遇到的问题:
- 中文文件名乱码(解决:添加
request.setCharacterEncoding("UTF-8")) - 临时存储目录权限不足(解决:修改
tomcat/conf/context.xml) - 重复文件名覆盖(解决:添加时间戳前缀)
明日计划:
- 学习图片缩略图生成
- 实现多文件批量上传
- 研究云存储OSS方案
关键收获:
- 理解了multipart/form-data的原理
- 掌握了文件流的基本操作
- 认识了文件上传的安全风险点

浙公网安备 33010602011771号