本文承接 Spring 學習筆記系列,詳細說明如何在 Spring MVC 中使用 JSR-303 Bean Validation 進行表單驗證,以及配置 Multipart 支援實現檔案上傳。
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.2.4.Final</version> </dependency>
注意:javax.validation 僅定義 API,必須搭配實作(如 Hibernate Validator)否則會報錯。
| 註解 | 說明 |
|---|---|
@NotNull | 值不能為 null(空字串不算 null) |
@NotEmpty | 字串/集合/陣列長度 > 0 |
@Size(min, max) | 長度範圍驗證 |
@Email | Email 格式驗證 |
@Pattern(regexp) | 正則表達式驗證 |
@Digits(integer, fraction) | 數字位數驗證 |
public class User implements Serializable {
@Size(min = 1, max = 32, message = "帳號長度應在 1-32 位之間")
private String username;
@NotEmpty(message = "密碼不能為空")
private String password;
@NotEmpty(message = "Email 不能為空")
@Email(message = "Email 格式不正確")
private String email;
@Size(min = 11, max = 11, message = "手機號長度必須為 11 位")
private String cellphone;
// getter/setter 省略
}
@Controller
@RequestMapping("/user")
public class UserController {
private final UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String processRegistration(@Valid User user, Errors errors) {
if (errors.hasErrors()) {
return "register"; // 驗證失敗返回註冊頁
}
// 業務邏輯...
return "redirect:/user/" + user.getUsername();
}
}
<%@ taglib prefix="sf" uri="https://www.springframework.org/tags/form" %>
<sf:form method="POST" action="/register/user/register" commandName="user">
<sf:errors path="*" element="div" cssClass="errors"/><br/>
<table>
<tr><td>UserName:</td><td><sf:input path="username" cssErrorClass="errors"/></td></tr>
<tr><td>Password:</td><td><sf:password path="password" cssErrorClass="errors"/></td></tr>
<tr><td>Email:</td><td><sf:input path="email" cssErrorClass="errors"/></td></tr>
<tr><td>CellPhone:</td><td><sf:input path="cellphone" cssErrorClass="errors"/></td></tr>
</table>
<input type="submit" value="Register"/>
</sf:form>
Spring 檔案上傳僅需三步:
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setMultipartConfig(new MultipartConfigElement(
"/tmp/uploads", // 臨時檔案目錄
2097152, // 單檔最大 2MB
4194304, // 請求總大小最大 4MB
0 // 檔案大小閾值,0 表示直接寫磁碟
));
}
@Bean
public MultipartResolver multipartResolver() throws IOException {
return new StandardServletMultipartResolver();
}
@RequestMapping(value = "/{username}", method = RequestMethod.POST)
public String showUserInfo(@RequestPart("icon") MultipartFile icon) throws IOException {
icon.transferTo(new File("/upload/path/" + icon.getOriginalFilename()));
return "user";
}
<form method="post" enctype="multipart/form-data"> <label>上傳頭像圖片?</label> <input type="file" name="icon" accept="image/jpeg, image/png" /> <button type="submit">確定</button> </form>
關鍵點:表單必須設定 enctype="multipart/form-data";推薦使用 MultipartFile 介面而非 byte[],可取得檔案名、大小、類型等資訊。