Spring MVC Controller 開發實戰:六大常規請求處理模式與代碼範例
基礎配置類
@Controller
@RequestMapping("/hello")
public class HelloMvcController {
// 所有示例方法定義在這裡
}
模式一:簡單無參數訪問
@GetMapping("/mvc")
public String helloMvc() {
return "home"; // 視圖名,由 ViewResolver 解析為 /WEB-INF/views/home.jsp 等
}
- 適用於靜態頁面跳轉、首頁展示。
- 返回
String 視為視圖名;返回 void 需手動寫響應。
模式二:Servlet API 獲取參數(不推薦)
@GetMapping("/views3")
public String viewCourse3(HttpServletRequest request) {
Integer courseId = Integer.valueOf(request.getParameter("courseId"));
System.out.println(courseId);
return "home";
}
- 強耦合 Servlet API,難以單元測試,參數轉換手動處理。
模式三:方法參數綁定 @RequestParam(推薦)
@GetMapping("/views")
public String viewCourse(@RequestParam("courseId") Integer courseId) {
System.out.println(courseId);
return "home";
}
- 自動類型轉換(String → Integer/Long/Date 等)。
required=false 可選參數,defaultValue 設置默認值。
- 支持
@RequestParam Map<String,String> params 綁定所有參數。
模式四:RESTful 風格路徑變量 @PathVariable
@GetMapping("/views/{courseId}")
public String viewCourse2(@PathVariable("courseId") Integer courseId, Map<String, Object> model) {
System.out.println("RESTful 風格: " + courseId);
model.put("courseId", courseId); // 傳遞給視圖
return "home";
}
- URL 語義化:
/courses/123 而非 /courses?id=123。
- 可組合多個路徑變量:
/users/{userId}/orders/{orderId}。
- 正則約束:
@PathVariable("id") @Pattern(regexp="\\d+") String id。
模式五:POST 表單提交 + 重定向 (PRG 模式)
@PostMapping("/save")
public String doSave(@ModelAttribute Course course) {
// courseService.save(course);
return "redirect:/hello/views/" + course.getCourseId(); // 重定向防止重複提交
}
@ModelAttribute 自動綁定表單字段到對象(需對象有無參構造器 + setter)。
redirect: 前綴觸發 302 重定向,瀏覽器地址欄變化,刷新不再提交 POST。
- 重定向攜帶數據可用
RedirectAttributes:attr.addFlashAttribute("msg", "保存成功")。
模式六:文件上傳
@PostMapping("/doUpload")
public String doUploadFile(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
// 1. 校驗類型/大小
// 2. 生成唯一文件名(UUID + 原後綴)
// 3. 保存到對象存儲/本地磁盤
// 4. 記錄數據庫
System.out.println("上傳文件: " + file.getOriginalFilename() + ", 大小: " + file.getSize());
}
return "success";
}
文件上傳必要配置
<!-- Spring MVC XML 配置 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="209715200"/> <!-- 200MB -->
<property name="defaultEncoding" value="UTF-8"/>
<property name="resolveLazily" value="true"/> <!-- 延遲解析,優化性能 -->
</bean>
# Spring Boot 配置
spring:
servlet:
multipart:
max-file-size: 200MB
max-request-size: 200MB
enabled: true
進階補充:統一響應封裝與異常處理
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public Result<Void> handleValidException(MethodArgumentNotValidException e) {
String msg = e.getBindingResult().getFieldErrors().stream()
.map(fe -> fe.getField() + ": " + fe.getDefaultMessage())
.collect(Collectors.joining("; "));
return Result.error(400, msg);
}
}
@Data @AllArgsConstructor
class Result<T> {
private int code; private String msg; private T data;
static <T> Result<T> ok(T data) { return new Result<>(200, "success", data); }
static <T> Result<T> error(int code, String msg) { return new Result<>(code, msg, null); }
}
總結對比表
| 模式 | 適用場景 | 關鍵注解 | 優點 | 缺點 |
| 無參訪問 | 靜態頁、首頁 | @GetMapping | 簡單直接 | 無參數交互 |
| Servlet API | 舊代碼維護 | HttpServletRequest | 兼容性 | 耦合強、手動轉換 |
| @RequestParam | 查詢參數、表單字段 | @RequestParam | 自動轉換、可選/默認值 | 參數多時方法簽名冗長 |
| @PathVariable | RESTful 資源定位 | @PathVariable | 語義清晰、SEO 友好 | 非層級資源難建模 |
| @ModelAttribute + redirect | 表單提交、修改操作 | @ModelAttribute, redirect: | 防重複提交、對象綁定 | 需遵循 PRG 模式 |
| MultipartFile | 文件上傳 | @RequestParam(MultipartFile) | 流式處理、大文件支持 | 需配置解析器 |
最佳實踐建議
- 優先使用 @RequestParam / @PathVariable,拒絕 Servlet API。
- DTO 校驗:
@Valid @RequestBody Dto dto + BindingResult / 全局異常處理。
- 統一返回格式:
Result<T> 封裝,@RestController 直接返回對象。
- 版本控制:URL 包含版本
/v1/users 或 Header Accept: application/vnd.myapp.v1+json。
- 安全:文件上傳必須校驗類型、大小、存儲路徑隔離、防止腳本執行。