前端 JS 校驗可繞過,服務端校驗是數據安全的最後防線。Spring MVC 整合 Hibernate Validator(JSR-303 實現),提供聲明式校驗能力,讓 Controller 專注業務邏輯。
僅需引入 hibernate-validator,傳遞依賴會自動包含 validation-api 與 jboss-logging:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
在 spring-mvc.xml 中定義 LocalValidatorFactoryBean 並指定錯誤訊息資源文件:
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<property name="validationMessageSource" ref="messageSource" />
</bean>
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list><value>classpath:CustomValidationMessages</value></list>
</property>
<property name="fileEncodings" value="utf-8" />
<property name="cacheSeconds" value="120" />
</bean>
<mvc:annotation-driven validator="validator" />
CustomValidationMessages.properties 定義錯誤碼與提示:
items.name.length.error=請輸入 1 到 30 個字符的商品名稱
items.createtime.isNull=請輸入商品的生產日期
在 ItemsCustom 上使用 JSR-303 註解,message 引用資源文件鍵:
public class ItemsCustom {
@Size(min=1, max=30, message="{items.name.length.error}")
private String name;
@NotNull(message="{items.createtime.isNull}")
private Date createtime;
// 其他字段、getter/setter
}
參數前加 @Validated,緊跟 BindingResult 獲取錯誤詳情:
@RequestMapping("/editItemsSubmit")
public String editItemsSubmit(Model model, @Validated ItemsCustom itemsCustom, BindingResult bindingResult) throws Exception {
if (bindingResult.hasErrors()) {
// 將錯誤列表傳給頁面
model.addAttribute("allErrors", bindingResult.getAllErrors());
return "items/editItems"; // 回顯表單頁
}
// 校驗通過業務邏輯
return "success";
}
JSP 使用 JSTL 迭代顯示:
<c:if test="${not empty allErrors}">
<c:forEach items="${allErrors}" var="error">
<div class="error">${error.defaultMessage}</div>
</c:forEach>
</c:if>
當同一 POJO 服務多個業務入口(如新增需校驗全部,修改只校驗名稱)時,使用分組機制:
public interface ValidGroup1 {} // 僅校驗名稱長度
public interface ValidGroup2 {} // 僅校驗價格非空
@Size(min=1, max=30, message="{items.name.length.error}", groups = {ValidGroup1.class})
private String name;
@RequestMapping("/editItemsSubmit")
public String editItemsSubmit(@Validated(ValidGroup1.class) ItemsCustom itemsCustom, BindingResult bindingResult) { ... }
這樣同一 POJO 可根據業務場景靈活切換校驗規則,避免創建大量相似 DTO 類。
Spring MVC + Hibernate Validator 實現了校驗邏輯與業務代碼的解耦,配合統一異常處理與國際化訊息,是構建健壯 Web 應用的標準方案。