1. 程式人生 > >springMVC 註解方式 驗證使用者輸入

springMVC 註解方式 驗證使用者輸入

Spring MVC支援與JSR 349Bean Validation  API 的整合。為了可以通過應用程式層來驗證資料,他提供了大量功能。

下面所示的程式碼片段定義了User域類,其中應用了一些驗證註解:

@Size 註解醬使用者名稱的長度設定為3~20之間

@Email 註解根據e-email的正則表示式來驗證輸入

@CreditCardNumber 註解根據Lubn演算法驗證輸入的數字

注意:

Luhn 演算法是一個簡單的模數-10(modulus-10)校驗公式,可用來驗證各種識別碼

@Pattern 註解根據一個正則表示式驗證密碼,比如第一個字元必須是字母,必須包含至少4個字元,但不能超過15個字元

為了節約篇幅,程式碼中省略了Getter和Setter方法

public class User{
    @Size(min=3,max=20)
    String username;

    @Email
    String email;

    @CreditCardNumber
    String ccNumber;

    @Pattern(regexp="^[a-zA-Z]\\w{3,14}$")
    String password;

     //getters  &  setters
}

為了啟用驗證,需要相專案中新增Bean驗證的實現。本列選擇Hibernate Validator框架來提供驗證功能。可以像下面的示例那樣將該專案作為一個Maven依賴新增到當前專案中。此外,Hibernate Validator會將Bean Validation API作為一個船隻依賴新增到專案中。

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.1.1.Final</version>
</dependency>
因為已經定義了模型,所以可以編寫新的包含該表單的JSP。所定義的表單分別針對User類的屬性包含了4個輸入元素,此外還包含4個errors標籤,以便顯示在每個輸入欄位可能發生的錯誤,通過使用請求對映/result,將表單提交到一個方法:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
    <%@taglib uri="http://www.springframework.org/tags/form" prefix="mvc" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring MVC Form Validation</title>
<style type="text/css">
.formFieldError{
	background-color:#FFC;		
}
</style>
</head>
<body>
    <h2>User Registration Form</h2>
    <mvc:form modelAttribute="user" action="result.mvc">
    	<table>
    		<tr>
    			<td><mvc:label path="username">User Name</mvc:label></td>
    			<td><mvc:input path="username" cssErrorClass="formFieldError"/></td>
    			<td><mvc:errors path="username"/></td>
    		</tr>
    		<tr>	
    			<td><mvc:label path="email">E-Mail</mvc:label></td>
    			<td><mvc:input path="email" cssErrorClass="formFieldError"/></td>
    			<td><mvc:errors path="email"/></td>
    		</tr>
    		<tr>
    			<td><mvc:label path="ccNumber">Credit Card Number</mvc:label></td>
    			<td><mvc:input path="ccNumber" cssErrorClass="formFieldError"/></td>
    			<td><mvc:errors path="ccNumber"/></td>
    		</tr>
    		<tr>
    			<td><mvc:label path="password">Password</mvc:label></td>
    			<td><mvc:input path="password" cssErrorClass="formFieldError"/></td>
    			<td><mvc:errors path="password"/></td>
    		</tr>
    		<tr>
    			<td colspan="3">
    				<input type="submit" value="Submit"/>
    			</td>
    		</tr>
    	</table>
    </mvc:form>
</body>
</html>
對於每一個errors標籤,都可以將其path特性設定為模型類的屬性名稱。但對於errors標籤來說,path特性則不是必須設定的。但如果沒有設定,則無法看到相關聯輸入欄位的錯誤訊息。如果想要在一個地方顯示所有錯誤,可醬path值設定為*,並將errors標籤放置在表單上。此外,本例還定義了一個樣式表類formFieldError.並將每個輸入欄位的cssErrorClass特性設定為該類。通過使用該錯誤類,當對一個輸入欄位驗證失敗時,該欄位的背景顏色將被設定為黃色。

用來處理表單提交的控制器方法如下所示:

@RequestMapping(value="/result")
	public ModelAndView processUser(@Valid User user,BindingResult result){
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("u",user);
		
		if(result.hasErrors()){
			modelAndView.setViewName("userForm");
		}
		else{
			modelAndView.setViewName("userResult");
		}
		return modelAndView;
	}
對使用者輸入的驗證由在user方法引數上設定的@Valid註解觸發,該註解被遞迴地應用到類的屬性,如果沒有設定該註解,就不會觸發Bean驗證。

processUser方法接收一個額外的引數result,該引數是一個BindingResult例項。通過使用該引數來檢查在將請求對映到域類屬性的過程中是否發生任何驗證錯誤(使用result.hasErrors()方法)。然後根據條件設定檢視,以便在輸入頁面向用戶顯示相關錯誤。

注意:

擋在模型特性上使用@Valid註解時,如果忽略了BindingResult型別的方法型別的方法引數,則可能在提交表單時遇到下面所示的問題:HTTP 400-The request sent by the client was syntactically incorrect. 所以請確保不要缺少BindingResult型別的方法引數。

如果所提交的表單帶有空輸入欄位,將得到如圖所示的輸出。

帶陰影的輸入框樣式來自cssErrorClass特性。圖所示的錯誤訊息是由框架預設設定的,如果要修改這些訊息,可以通過使用註解設定新的訊息,比如對於密碼欄位,可以設定以下訊息:


通過使用該方法,可以讓顯示的訊息比預設訊息更加易於理解,但它仍然缺乏國際化,因為訊息本身是硬編碼實現的。

為了配置驗證,首先需要相Web應用程式的上下文中新增LocalValidatorFactoryBean和ReloadableResourceBundleMessageSource Bean定義,此外,還需要在mvc明明空間的annotation-driven標籤中定義驗證程式:

<mvc:annotation-driven validator="validator"/>

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
   <property name="basename" value="classpath:messages"/>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
  <property name="validationMessageSource" ref="messageSource"/>
</bean>
此時,ReloadableResourceBundleMessageSource引用一個屬性檔案,該檔案包含以鍵值對形式存在的訊息。檔案應該位於應用程式的類路徑下,其基本名稱為messages
如果你正在使用Maven作為開發工具,那麼可在src/main/resources資料夾下建立該屬性檔案。根據區域設定不同,該檔案可能有所不同,比如區域設定為U.S.,檔案可能是message_en_US.properties,而區域設定為Turkish,則檔案為message_tr_TR.properties,或者也可以直接將其定義為message.properties。

接下來,可以在註解中未訊息定義鍵


如果使用該方法,則需要將一個訊息鍵新增到每個註解(將其用大括號括起來)。另一種選擇是根據註解,模型特性以及所使用的路徑名稱定義鍵值。此時,鍵的註解為AnnotationName.ModeAttributeName.PathName。讓我們來看一個示例,比如,對於一個使用@Pattern註解標識的password欄位,在屬性檔案中定義的鍵值應該是Pattern.user.password.相比於前一種方法,該方法是非強制性的,因為在程式碼中沒有硬編碼資訊。