Spring MVC 使用介紹(十三)數據驗證 (一)基本介紹

1、消息處理功能html

Spring提供MessageSource接口用於提供消息處理功能:java

public interface MessageSource {
    String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
    String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
    String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}

Spring提供了兩個默認實現:git

StaticMessageSource      // 測試用
ResourceBundleMessageSource   // 用於生產環境

ApplicationContext接口擴展了MessageSource接口,當ApplicationContext被加載時,它會自動在context中查找已定義爲MessageSource類型的bean。此bean的名稱須爲messageSource。若是找到,那麼全部對上述方法的調用將被委託給該bean。不然ApplicationContext會在其父類中查找是否含有同名的bean。若是有,就把它做爲MessageSource。若是它最終沒有找到任何的消息源,一個空的StaticMessageSource將會被實例化,使它可以接受上述方法的調用。正則表達式

示例以下:spring

屬性文件api

# exception.properties
message.arg=the {0} {1} is requred.

# format.properties
message=這是一條測試消息

# format_en_GB.properties
message=this is a test

spring 配置(spring-validation.xml)mvc

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd ">

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>classpath:format</value>
                <value>classpath:exception</value>
            </list>
        </property>
        <property name="fileEncodings">
            <props>
                <prop key="classpath:format">utf-8</prop>
            </props>
        </property>
    </bean>
    
</beans>

測試app

public class MessageTest {

    public static void main(String[] args) {
        
        MessageSource ms = new ClassPathXmlApplicationContext("spring-validation.xml");
        String msg1 = ms.getMessage("message", null, "yeah", null); 
        String msg2 = ms.getMessage("message.arg", new Object[] { "aa", "bb" }, "yeah", null); // 參數定製
        String msg3 = ms.getMessage("message", null, "yeah", Locale.UK);  // 支持國際化
        System.out.println(msg1);
        System.out.println(msg2);
        System.out.println(msg3);
    }

}

運行結果ide

這是一條測試消息
the aa bb is requred.
this is a test

補充:spring提供了MessageSourceAware接口,用於在bean建立時自動注入MessageSource。post

 

 2、數據驗證

JSR-303 (Bean Validation 1.0)定義了基於註解JavaBean數據驗證規範,註解以下:

@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(value)              被註釋的元素必須符合指定的正則表達式
@Valid                   被註釋的元素必須爲對象,表示遞歸驗證對象屬性

hibernate validator 在JSR303的基礎上對校驗註解進行了擴展,擴展註解以下:

@Emai                    被註釋的元素必須是電子郵件格式
@Length                  被註釋的字符串大小必須在指定範圍內
@NotEmpty                被註釋的字符串必須非空
@Range                    被註釋的元素必須在合適的範圍內

全部被支持的註解列表參見:hibernate-validator -> /org/hibernate/validator/ValidationMessages.properties

spring在hibernate validator基礎上對JavaBean的數據校驗方式進行了封裝,配置與使用方式以下:

一、添加依賴

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.16.Final</version>
</dependency>

二、添加配置

<!-- validator bean -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">  
        <property name="providerClass"  value="org.hibernate.validator.HibernateValidator"/>  
        <property name="validationMessageSource" ref="messageSource"/>  
</bean> 

<!-- 註冊(註冊方式與Converter相同,參見Spring MVC 使用介紹(八)—— 類型轉換) -->
<mvc:annotation-driven validator="validator" />

  注:messageSource的配置與上例相同

# format.properties
msg.age=性別須大於{value}歲

三、使用

Java Bean

public class Person {
    @NotNull
    private String name;
    
    @Min(value = 12, message = "{msg.age2}")
    private int age;
    ...
}    

controller

@ControllerAdvice
public class MyControllerAdvice {
    @ResponseBody
    @ExceptionHandler
    public Map<String, String> errorhandler(Exception ex) {
        BindException e = (BindException) ex;
        Map<String, String> map = new HashMap<>();
        map.put("error", e.getBindingResult().getFieldError().getDefaultMessage());
        return map;
    }
}
@RestController
public class ValidController {
    @RequestMapping("/test1")
    public Person test1(@Valid Person person) {
        return person;
    }
}

四、測試

訪問:http://localhost:8080/shiro-test/test1?name=12&age=6,輸出

{"error":"性別須大於12歲"}

訪問:http://localhost:8080/shiro-test/test1?age=20,輸出

{"error":"must not be null"}

 

3、錯誤消息

數據驗證錯誤消息的指定有多種方式:

一、默認錯誤消息

默認的錯誤消息文件是/org/hibernate/validator/ValidationMessages.properties,以下圖所示:

消息鍵默認爲:驗證約束註解的全限定類名.message

當不指定驗證註解的message屬性時,則使用默認消息

二、覆蓋默認錯誤消息

方法很簡單:在MessageSource的屬性文件中依據默認消息鍵從新定義鍵值:

# format.properties
javax.validation.constraints.NotNull.message         = 不能爲空

三、自定義錯誤消息

在屬性文件中定義錯誤消息,使用註解的message屬性引用:

# format.properties
msg.notnull=不能爲空
public class Person {
    @NotNull(message = "{msg.notnull}")
    private String name;
    ...
}

3.1 消息佔位符

可在錯誤消息中使用佔位符獲取約束值,規則爲:{驗證註解屬性名},如@Length有min和max屬性,可在消息文件中使用{min}和{max}獲取;@Max有value屬性,可以使用{value}獲取

msg.age=性別須大於{value}歲

3.2 EL表達式

可在錯誤消息中使用EL表達式,規則爲:${表達式},如可以使用${validatedValue}獲取驗證值,使用${min > 1 ? '大於1' : '小於等於1'}添加邏輯判斷:

javax.validation.constraints.Size.message = [${validatedValue}]須大於等於{min}字符
javax.validation.constraints.Min.message = 數量${min > 1 ? '大於1' : '小於等於1'}

在EL表達式中,可以使用java.util.Formatter類型的formatter變量進行格式化:

${formatter.format("%04d", min)}

 

參考:

spring中ResourceBundleMessageSource的配置使用方法

SpringMVC數據驗證——第七章 註解式控制器的數據驗證、類型轉換及格式化——跟着開濤學SpringMVC

Java Bean Validation 最佳實踐

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC

JAVA字段校驗(validation)

相關文章
相關標籤/搜索