須要檢查的java bean html
Entity.javajava
import javax.validation.constraints.Max; import org.hibernate.validator.constraints.Length; public class Entity { @Max(value=3)//最大值爲3 private int age; @Length(max=1) //字符串長度最大爲1,hibernate 擴展的 private String name; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
值校驗的測試類git
import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; public class Tv { public static void main(String[] args) { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Entity entity = new Entity(); entity.setAge(12); entity.setName("admin"); Set<ConstraintViolation<Entity>> constraintViolations = validator.validate(entity); for (ConstraintViolation<Entity> constraintViolation : constraintViolations) { System.out.println("對象屬性:"+constraintViolation.getPropertyPath()); System.out.println("國際化key:"+constraintViolation.getMessageTemplate()); System.out.println("錯誤信息:"+constraintViolation.getMessage()); } } }
輸出結果web
這裏有一個國際化的key值,國際化文件在org.hibernate.validator下面的一系列的properites文件裏面,若是須要自定義那麼能夠拷貝出來放在src目錄下正則表達式
這裏咱們拷貝一個出來,新增一個key爲maxlength=字符串長度最大不能超過{max} ,可使用動態參數,這裏的max值就是註解裏面設定的值spring
而後修改Entity.java,name屬性的message="{maxlength}"api
@Length(max=1,message="{maxlength}") //{maxlength}對應配置文件中的key. 必須有{} private String name;
再次運行結果以下mvc
首先自定義一個註解CannotContainSpaces (不能包含空格)app
import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; @Constraint(validatedBy = CannotContainSpacesValidator.class) //具體的實現 @Target( { java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.FIELD }) @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Documented public @interface CannotContainSpaces { String message() default "{Cannot.contain.Spaces}"; //提示信息,能夠寫死,能夠填寫國際化的key int length() default 5; //下面這兩個屬性必須添加 Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
具體實現類CannotContainSpacesValidator.javajsp
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class CannotContainSpacesValidator implements ConstraintValidator<CannotContainSpaces, String> { private int len; /** * 初始參數,獲取註解中length的值 */ @Override public void initialize(CannotContainSpaces arg0) { this.len = arg0.length(); } @Override public boolean isValid(String str, ConstraintValidatorContext constraintValidatorContext) { if(str != null){ if(str.indexOf(" ") < 0){ return true; } }else{ constraintValidatorContext.disableDefaultConstraintViolation();//禁用默認的message的值 //從新添加錯誤提示語句 constraintValidatorContext .buildConstraintViolationWithTemplate("字符串不能爲空").addConstraintViolation(); } return false; } }
使用的時候直接註解到對象的屬性上面就能夠了
@CannotContainSpaces private String name;
測試當name包含空格的時候 entity.setName("xx xx");
當name爲null的時候
首先新增配置文件內容(實體類裏面的註解與上面徹底相同)
<!-- 國際化配置 --> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver" /> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:messages/messages</value> <value>classpath:messages/Validation</value> </list> </property> <property name="useCodeAsDefaultMessage" value="true" /> </bean> <!-- 註冊驗證器 --> <mvc:annotation-driven validator="validator" /> <!-- 註冊驗證器 補充方式二--> <!-- <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="webBindingInitializer"> <ref bean="webBindingInitializer" /> </property> </bean> <bean id="webBindingInitializer" class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"> <property name="validator" ref="validator" /> </bean> --> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/> <!-- 這裏配置將使用上面國際化配置的messageSource --> <property name="validationMessageSource" ref="messageSource"/> </bean>
在Spring MVC 控制器中方法屬性以下
/** * 這裏的@Valid必須書寫, bindingResult參數也必須書寫在後面,不然驗證不經過就會返回400 * @param entity * @param result * @return */ @RequestMapping(value="/valid") public String validator(@Valid Entity entity,BindingResult result){ if(result.hasErrors()){ //若是嚴重沒有經過,跳轉提示 return "error"; }else{ //繼續業務邏輯 } return "success"; }
error.jsp中以下
導入spring標籤庫
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!-- commandName 控制器參數中對象名稱 --> <form:form commandName="entity"> <!-- 顯示所有錯誤信息用* --> <form:errors path="*"/> </form:form> <hr/> <!-- 對象名稱.屬性名稱 若是該對象的指定屬性沒有經過校驗那麼顯示錯誤信息(根據當前語言顯示不一樣國家的文字) --> <form:errors path="entity.name"/>
校驗註解說明
Bean Validation 中內置的 constraint @Null 被註釋的元素必須爲 null @NotNull 被註釋的元素必須不爲 null @AssertTrue 被註釋的元素必須爲 true @AssertFalse 被註釋的元素必須爲 false @Min(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值 @Max(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值 @DecimalMin(value) 被註釋的元素必須是一個數字,其值必須大於等於指定的最小值 @DecimalMax(value) 被註釋的元素必須是一個數字,其值必須小於等於指定的最大值 @Size(max=, min=) 被註釋的元素的大小必須在指定的範圍內 @Digits (integer, fraction) 被註釋的元素必須是一個數字,其值必須在可接受的範圍內 @Past 被註釋的元素必須是一個過去的日期 @Future 被註釋的元素必須是一個未來的日期 @Pattern(regex=,flag=) 被註釋的元素必須符合指定的正則表達式 Hibernate Validator 附加的 constraint @NotBlank(message =) 驗證字符串非null,且長度必須大於0 @Email 被註釋的元素必須是電子郵箱地址 @Length(min=,max=) 被註釋的字符串的大小必須在指定的範圍內 @NotEmpty 被註釋的字符串的必須非空 @Range(min=,max=,message=) 被註釋的元素必須在合適的範圍內
注意
①:在整合Spring MVC的時候,ValidationMessages_zh_CN.properties文件若是不是放在src目錄下(如上面放在src/messages/下面) 那麼在屬性文件裏面不能使用動態參數獲取了(如${length} ${max}這些). 必須將hibernate validation的國際化屬性所有放到src目錄下面才能夠(不曉得爲何,若是你能解決順便留個言)
②:我這裏使用的是spring 4.1 + hibernate validation 5.1 ,若是你使用的是spring 3.2 須要對於的hibernate validation版本是 4.x的 否則在配置
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
這個的是會報錯,
當SpringMVC將接收到的參數映射成modelAttribute時,可能會出現異常,好比參數是字符型,接收對象的屬性是數值型,則轉換異常。此時SpringMVC也會把異常信息放到BindingResult中。可是異常信息沒有通過國際化處理,若是要轉換爲國際化的信息,則要本身處理,方式以下:
經過BindingResult獲取到FieldError對象error,在經過messageSource.getMessage()方法獲取到國際化後的異常信息
@Autowired private MessageSource messageSource; ... FieldError error = bindingResult.getFieldError("fieldName"); String errorMessage = messageSource.getMessage(error, Locale.getDefault());