Spring MVC 是一个用于构建基于Java的Web应用的框架,它提供了一个易于使用的开发环境来创建复杂的Web应用。本文将详细介绍如何在Spring MVC中实现图片的上传和下载功能。
一、环境准备
1. **创建Spring MVC项目**:
- 使用Spring Initializr生成一个基础的Spring Boot项目,选择`Web`依赖项。
- 添加Maven依赖:
```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> ```
2. **配置文件**:
- 在`application.properties`文件中添加以下配置:
```properties spring.servlet.multipart.enabled=true spring.servlet.multipart.max-file-size=2MB spring.servlet.multipart.max-request-size=2MB ```
二、图片上传功能
1. **创建上传表单**:
- 在`src/main/resources/templates`目录下创建`upload.html`文件,内容如下:
```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Upload Image</title> </head> <body> <h1>Upload Image</h1> <form method="POST" enctype="multipart/form-data" th:action="@{/upload}"> <input type="file" name="file" accept="image/*"/> <button type="submit">Upload</button> </form> </body> </html> ```
2. **创建Controller**:
- 在`src/main/java/com/example/demo/controller`目录下创建`UploadController.java`文件,内容如下:
```java package com.example.demo.controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; @Controller public class UploadController { private static final String UPLOAD_DIR = "uploads/"; @GetMapping("/upload") public String uploadForm() { return "upload"; } @PostMapping("/upload") public String uploadFile(@RequestParam("file") MultipartFile file, Model model) { if (file.isEmpty()) { model.addAttribute("message", "Please select a file to upload."); return "upload"; } try { // 获取文件名 String fileName = file.getOriginalFilename(); // 设置保存路径 Path path = Paths.get(UPLOAD_DIR + fileName); // 保存文件到服务器 file.transferTo(path.toFile()); model.addAttribute("message", "File uploaded successfully: " + fileName); } catch (IOException e) { model.addAttribute("message", "Failed to upload file: " + e.getMessage()); } return "upload"; } } ```
3. **创建保存目录**:
- 在项目根目录下创建一个`uploads`文件夹,用于存放上传的图片。
三、图片下载功能
1. **创建下载表单**:
- 在`src/main/resources/templates`目录下创建`download.html`文件,内容如下:
```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Download Image</title> </head> <body> <h1>Download Image</h1> <form method="GET" th:action="@{/download}"> <input type="text" name="filename" placeholder="Enter filename"/> <button type="submit">Download</button> </form> </body> </html> ```
2. **更新Controller**:
- 在`UploadController.java`文件中添加下载功能的代码:
```java import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestParam; @GetMapping("/download") public ResponseEntity<Resource> downloadFile(@RequestParam("filename") String filename) { File file = new File(UPLOAD_DIR + filename); if (!file.exists()) { return ResponseEntity.notFound().build(); } Resource resource = new FileSystemResource(file); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"") .body(resource); } ```
四、测试功能
1. **启动项目**:
- 运行Spring Boot项目,启动Web服务器。
2. **上传图片**:
- 在浏览器中访问`http://localhost:8080/upload`,选择图片文件并点击上传按钮。
3. **下载图片**:
- 在浏览器中访问`http://localhost:8080/download`,输入上传的文件名并点击下载按钮。
通过以上步骤,我们成功实现了Spring MVC中图片的上传和下载功能。
五、完善上传和下载功能
1. **改进上传功能**:
- 在上传时,避免文件名冲突,可以添加时间戳或UUID。
- 对上传文件进行类型检查,只允许图片格式。
修改后的`UploadController.java`如下:
```java import org.springframework.util.StringUtils; @PostMapping("/upload") public String uploadFile(@RequestParam("file") MultipartFile file, Model model) { if (file.isEmpty()) { model.addAttribute("message", "Please select a file to upload."); return "upload"; } try { // 获取文件名,并添加时间戳避免冲突 String originalFileName = StringUtils.cleanPath(file.getOriginalFilename()); String fileName = System.currentTimeMillis() + "_" + originalFileName; // 检查文件类型 String fileType = file.getContentType(); if (fileType == null || !fileType.startsWith("image")) { model.addAttribute("message", "Only image files are allowed."); return "upload"; } // 设置保存路径 Path path = Paths.get(UPLOAD_DIR + fileName); // 保存文件到服务器 file.transferTo(path.toFile()); model.addAttribute("message", "File uploaded successfully: " + fileName); } catch (IOException e) { model.addAttribute("message", "Failed to upload file: " + e.getMessage()); } return "upload"; } ```
2. **改进下载功能**:
- 提供下载文件列表,避免手动输入文件名。
- 增加文件不存在时的友好提示。
修改后的`UploadController.java`如下:
```java import java.util.stream.Collectors; import java.util.stream.Stream; @GetMapping("/download") public String downloadForm(Model model) { File folder = new File(UPLOAD_DIR); String[] files = folder.list(); if (files != null) { model.addAttribute("files", Stream.of(files).collect(Collectors.toList())); } else { model.addAttribute("files", new ArrayList<>()); } return "download"; } @GetMapping("/download/{filename}") public ResponseEntity<Resource> downloadFile(@PathVariable("filename") String filename) { File file = new File(UPLOAD_DIR + filename); if (!file.exists()) { return ResponseEntity.notFound().build(); } Resource resource = new FileSystemResource(file); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"") .body(resource); } ```
同时修改`download.html`,如下:
```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Download Image</title> </head> <body> <h1>Download Image</h1> <ul> <li th:each="file : ${files}"> <a th:href="@{/download/{filename}(filename=${file})}" th:text="${file}">Filename</a> </li> </ul> </body> </html> ```
六、文件大小限制与异常处理
1. **文件大小限制**:
- 配置文件大小限制,防止上传过大的文件影响服务器性能。
在`application.properties`文件中添加:
```properties spring.servlet.multipart.max-file-size=5MB spring.servlet.multipart.max-request-size=5MB ```
2. **异常处理**:
- 创建全局异常处理器来处理文件上传相关的异常。
在`src/main/java/com/example/demo/exception`目录下创建`GlobalExceptionHandler.java`文件:
```java package com.example.demo.exception; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.multipart.MaxUploadSizeExceededException; import org.springframework.web.servlet.mvc.support.RedirectAttributes; @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(MaxUploadSizeExceededException.class) public String handleMaxSizeException(MaxUploadSizeExceededException exc, RedirectAttributes redirectAttributes) { redirectAttributes.addFlashAttribute("message", "File too large!"); return "redirect:/upload"; } } ```
七、项目结构总结
项目结构如下:
``` src ├── main │ ├── java │ │ └── com │ │ └── example │ │ └── demo │ │ ├── controller │ │ │ └── UploadController.java │ │ └── exception │ │ └── GlobalExceptionHandler.java │ ├── resources │ │ └── templates │ │ ├── upload.html │ │ └── download.html │ └── application.properties └── test ```
通过以上步骤,你已经成功实现了Spring MVC中图片的上传和下载功能,并且处理了文件大小限制和异常情况。
八、测试上传和下载功能
1. **启动项目**:
- 运行Spring Boot项目,启动Web服务器。
2. **上传图片**:
- 在浏览器中访问`http://localhost:8080/upload`,选择图片文件并点击上传按钮。
3. **下载图片**:
- 在浏览器中访问`http://localhost:8080/download`,点击文件名链接下载图片。