亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

Spring MVC 綁定表單數據

1. 前言

在 WEB 應用程序中,經常會以表單的方式提交數據。使用 Spring MVC 或其它 WEB MVC 框架開發時,框架本身會提供以對象為單位自動封裝表單中數據的功能。

本節課通過一個用戶注冊的小例子,和大家聊聊 Spring MVC 是如何優雅的以對象的方式封裝表單中的數據。

本節課程的重點就是請你一定要跟著課程案例練習一遍。

2. 對象 / 表單

以表單的方式提交數據有一個優點,可以把邏輯上具有內在聯系的多個數據同時發送給服務器。原生 Servlet 開發時,服務器端的響應組件(Servlet)中,需要開發者編寫代碼從請求包一個一個解析出提交過來的數據。

如果數據量不多,倒還好,如果數據量較多,一個一個解析,枯燥乏味的工作除了讓人厭煩,且會耽誤開發效率。

來!通過一個案例,體會 Spring MVC 是如何一步到位解析大量數據的。

案例需求描述: 實現用戶注冊功能。

流程分析: 通過注冊頁面,用戶輸入個人信息。表單中的數據以 POST 的請求方式提交至服務器,服務器端的控制器對提交過來的數據進行處理。

實現流程:

2.1 編寫頁面

編寫注冊頁面,表單的提交方法設置為 POST 。

Tips: 無論數據是以 GET 或 POST 提交,本質沒多大區別,僅表現在語義上的差異性。也就是說,此處使用 GET 方式提交并不影響結果。

<form action="user/register" method="post">
	用戶名:<input type="text" value="" name="userName" /> 
    <br />
    密碼:<inpu type="password" value="" name="userName" />
    <br />
    <input type="submit" value="注冊" name="btnRegister" />
    <input type="reset"  value="重置" name="btnReset" />
</form>

2.2 分析控制器中的邏輯流程

注冊頁面中提交的用戶數據最終會交給服務器端的用戶控制器完成,控制器中的處理流程應該分 3 步走:

  1. 從請求包中解析出客戶端提交過來的注冊數據;
  2. 處理注冊數據。核心業務邏輯就是添加數據到數據庫中;
  3. 根據處理結果進行頁面跳轉。

Tips: 本節課程主要講解數據綁定,會淡化后面的兩個邏輯。

2.3 綁定數據

使用 @RequestParam 注解

Spring MVC 提供有 @RequestParam 注解,通過給定參數名,可以自動綁定請求包中的同名參數的數據。

代碼如下:

@Controller
@RequestMapping("/user")
public class UserAction {
	@RequestMapping("/register")
	public String register(@RequestParam("userName") String userNmae,
			@RequestParam("userPassword") String userPassword) {
		System.out.println(userNmae);
		System.out.println(userPassword);
		return null;
	}
}

此處,使用 @RequestParam 注解綁定請求包中的數據,有 2 個弊端:

  • 如果請求包中傳過來的數據較多,控制器中響應方法的參數也會增多,代碼臃腫不好維護;

  • Java 語言最大的特色是面向對象編程(OOP)。很顯然,userNameuserPassword 都是用戶的信息,以一種拆離的方式分別注入數據沒有體現出 OOP 的優點。

那么,有沒有一種更好的替代方案或者說有一種很 OOP 的方案呢?

以 OOP 方式綁定數據

OOP 的角度分析,在應用程序中必然會存在一個描述用戶的類。

public class User {
	private String userName;
   	private String userPassword;
    //……
}

能不能直接把請求包中提交的數據綁定到 User 類型中?

答案是肯定的,而且實現起來非常簡單,只需要把控制器方法的參數修改成對象類型便可。

@RequestMapping("/register",method = RequestMethod.POST)
public String register(User user) {
	System.out.println(user);
	return null;
}

不需要使用額外的任何注解,就可以直接綁定表單中的數據。

為什么表單中的數據能自動綁定到對象上?

原理很簡單,表單中數據以 key=value&key=value 的方式提交,此處的 key 實質是表單控件的名稱。前面的注冊表單中的數據在請求包中的格式形式如下:

userNname=abc&userPassword=123456

圖片描述

如上圖所示,Spring MVC 能自動解析這個數據,然后自動注入到對象的同名屬性中。所以一定要保證對象的屬性名與表單中提交數據時使用的參數名(key)一致。

數據解析成功后,理論上講應該要把數據送到數據庫中,本章節暫不涉及到數據庫操作。只做業務邏輯模擬。

@RequestMapping(value="/register",method = RequestMethod.POST)
public String register(User user) {
	if("abc".equals(user.getUserName()) && "123456".equals(user.getUserPassword()) ) {
		return "success";
	}else {
		return "fail";
	}	
}

3. 對象級聯

OOP 代碼中經常會出現類似于 A 對象引用 B 對象,B 對象引用 C 對象的現象。 類似于現實生活中的小王有一輛汽車,汽車有一把鑰匙……

如果每一個用戶都有一輛汽車,用 OOP 描述,意味著 User 類中有一個對 Car 的引用類型屬性。

public class User {
	private String userName;
	private String userPassword;
	private Car car;
    //……
}

假設 Car 類結構如下:

public class Car {
private String carType;
private String carColor;
//……
}

在注冊時,除了要輸入用戶信息之外,還需要指定用戶所擁有的汽車類型、顏色。那么,控制器是否能自動綁定用戶以及汽車數據?

Tips: 為什么注冊時要輸入汽車信息,不要糾結,只是一個用來說明問題的例子。

答案是肯定的。

只需要在表單頁面中添加如下代碼,控制器端不做任何修改。如此,除了能接收用戶數據外,還能接收汽車的信息。

<form action="user/register" method="post">
	用戶名:<input type="text" value="" name="userName" /> 
	<br />
	密碼:<input type="password" value="" name="userPassword" /> <br />
	汽車類型:<input type="text" value="" name="car.carType" /> <br />
	汽車顏色:<input  type="text" value="" name="car.carColor" /> <br />
	<input  type="submit" value="注冊" name="btnRegister" />
	<input type="reset"  value="重置" name="btnReset" />
</form>

也就是說,Spring MVC 支持對象級聯自動數據綁定。

圖片描述

Spring MVC 支持多層級的對象級聯。

4. 小結

本節課程主要是和大家講解如何綁定表單中的數據。有 2 種方式,一是使用 @RequestParam 注解,另一個就是通過一個對象參數直接綁定數據。

Spring MVC 的自動綁定功能非常強大。在使用的時候可根據自己的需要自行選擇。

當然,以 OOP 的形式綁定數據定當是最佳、快速的選擇。