衆所周知,springmvc是用來處理頁面的一些請求,而後將數據再經過視圖返回給用戶的,前面的幾篇博文中使用的都是靜態數據,爲了能快速入門springmvc,在這一篇博文中,我將總結一下springmvc中如何接收前臺頁面的參數,即springmvc中的參數綁定問題。html
咱們能夠回憶一下,在struts2中,是經過在Action中定義一個成員變量來接收前臺傳進來的參數,而在springmvc中,接收頁面提交的數據是經過方法形參來接收的。從客戶端請求的key/value數據,通過參數綁定,將key/value數據綁定到controller方法的形參上,而後就能夠在controller中使用該參數了。來看一下這個過程:
因此咱們知道,是springmvc提供了不少轉換器來將頁面參數綁定到controller方法的形參上,關於自定義converter,我下面會提到。大概瞭解了該過程後,下面開始作具體的總結。java
springmvc中,有支持的默認類型的綁定。也就是說,直接在controller方法形參上定義默認類型的對象,就可使用這些對象。web
- HttpServletRequest對象
- HttpServletResponse對象
- HttpSession對象
- Model/ModelMap對象
在參數綁定過程當中,若是遇到上面類型就直接進行綁定。也就是說,咱們能夠在controller的方法的形參中直接定義上面這些類型的參數,springmvc會自動綁定。這裏要說明一下的就是Model/ModelMap對象,Model是一個接口,ModelMap是一個接口實現 ,做用是將Model數據填充到request域,跟ModelAndView相似,關於它的使用,我在下面和簡單類型參數綁定一塊兒說。spring
總結這個仍是以需求爲例吧,這樣比較容易理解,假設如今有個需求:根據商品的id來修改對應點商品信息。因此前臺頁面確定要傳進來該商品的id,而後springmvc的controller進行處理,返回一個修改商品信息的頁面。關於前臺頁面的東西都很簡單,我就不貼代碼了,主要部分截個圖,具體的代碼在文章最後有下載地址。
前臺頁面經過url將參數傳遞過來,請求的是editItems.action。
下面寫controller中的editItems方法:數據庫
@RequestMapping("/editItems") public String editItems(Model model, Integer id) throws Exception { //根據id查詢對應的Items ItemsCustom itemsCustom = itemsService.findItemsById(id); model.addAttribute("itemsCustom", itemsCustom); //經過形參中的model將model數據傳到頁面 //至關於modelAndView.addObject方法 return "/WEB-INF/jsp/items/editItems.jsp"; }
這是個很簡單的demo,從上面的代碼中能夠看出model能夠直接做爲參數,springmvc默認會綁定它,而後使用model將查詢到的數據放到request域中,這樣就能夠在前臺頁面取出該數據了。
要注意一點的是,簡單類型的綁定中,方法形參中的參數名要和前臺傳進來的名同樣才能完成參數的綁定。那有人要問了,若是有特殊需求(好比更好的可讀性?),這裏定義的參數名就是不同,那咋整呢?有解決辦法麼?有!咱們可使用註解@RequestParam對簡單的類型進行參數綁定,以下:
因此說,若是不使用@RequestParam,要求request傳入參數名稱和controller方法的形參名稱一致,方可綁定成功。若是使用@RequestParam,不用限制request傳入參數名稱和controller方法的形參名稱一致。經過@RequestParam中的required屬性指定參數是否必需要傳入,若是設置爲true,沒有傳入參數就會報錯。數組
再來總結下pojo類型的綁定,繼續上面的案例,當頁面展現了商品詳細信息後,我作了修改,而後點擊提交,後臺應該將我提交的這些參數所有更新到數據庫的items表中,也就是說,我提交的這些參數要綁定到Items對象或者其擴展對象中。先看一下Items中都有哪些屬性:
能夠看到,有各類類型的屬性,當咱們提交後,要將這些屬性所有封裝到一個pojo中,而後去更新數據庫。
綁定很簡單,對於基本類型,要求頁面中input標籤的name屬性值和controller的pojo形參中的屬性名稱一致,便可將頁面中數據綁定到pojo。也就是說前臺頁面傳進來的name要和要封裝的pojo屬性名如出一轍,而後就能夠將該pojo做爲形參放到controller的方法中,以下:
這樣就能將前臺表單傳進來的不一樣屬性值封裝到ItemsCustom中了。可是運行一下就會發現報錯,報錯的信息是沒法將String類型轉換成java.util.Date類型,由於上面Items中有一個屬性是Date類型的createtime。這就須要咱們本身定義轉換器了,這也是這部分的重點,下面咱們本身定義一個日期轉換器:mvc
//須要實現Converter接口,這裏是將String類型轉換成Date類型 public class CustomDateConverter implements Converter<String, Date> { @Override public Date convert(String source) { //實現 將日期串轉成日期類型(格式是yyyy-MM-dd HH:mm:ss) SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { //轉成直接返回 return simpleDateFormat.parse(source); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } //若是參數綁定失敗返回null return null; } }
定義好了轉換器後,須要在springmvc.xml中進行以下配置:
如今就能夠了,springmvc就能根據這個轉換器將String類型正確轉換成Date類型,而後封裝到ItemsCustom中去了。
這裏說一個小小的插曲:修改商品詳細信息後提交,可能會有中文亂碼問題,表達提交都是post方式,springmvc中關於post方式的中文亂碼問題能夠在web.xml中配置一個過濾器來解決,以下:
app
這個包裝類型pojo與上面普通的pojo有啥區別呢?包裝類型pojo指的是pojo中有另外一個也是pojo的屬性,即pojo套pojo,爲何會設計這種pojo呢?在前面的博文中我也有提到,這種組合的設計方法對於後期程序的擴展頗有用,好比複雜的查詢條件就須要包裝到這種包裝類型中。
那麼該如何綁定呢?有兩個思路:jsp
- 在形參中添加HttpServletRequest request參數,經過request接收查詢條件參數。
- 在形參中讓包裝類型的pojo接收查詢條件參數。
第一種方式就跟原始servlet差很少,這裏使用第二種方法,咱們傳進來一個包裝類型的pojo。看一下這個包裝類型的pojo:
這個包裝pojo中還有一個ItemsCustom類,這個類繼承了Items類,而且用來擴展與Items相關的User對象中的相關信息。因此這個ItemsCustom中有name屬性,假如咱們要想將前臺傳進來的name屬性封裝到ItemsCustom中的name屬性中,該如何傳入呢?這就是包裝類型的pojo參數綁定問題。
很簡單,在前臺咱們能夠經過這種方式來傳:
而後controller中方法的形參傳入包裝類型的pojo,即ItemsQueryVo,打個斷點,便可查看值有沒有傳進來。以下:
這樣就能根據用戶傳進來的參數,進行復制的查詢操做了。ide
數組的綁定指的是前臺傳來多個同一類型的數據,咱們在controller中使用數組形參來接收前臺傳來的數據。仍是以案例來驅動這部份內容,好比如今咱們要批量刪除商品,那麼咱們須要勾選好幾個商品,這些商品都有id號,在controller中,咱們須要將這些id號所有獲取並放到一個數組中,而後再根據數組中的id號挨個刪除數據庫中對應的項。那麼該如何綁定呢?其實也很簡單,以下:
controller的方法定義爲:
對應前臺傳入的參數爲:
這樣就能將前臺傳入的多個id綁定到數組中,而後咱們就能夠從數組中拿出要刪除的商品的id了。
一般在須要批量提交數據時,將提交的數據綁定到list<pojo>
中,好比:成績錄入(錄入多門課成績,批量提交),在這裏咱們假設有需求:批量商品修改,在頁面輸入多個商品信息,將多個商品信息提交到controller方法中,即一次性更新多個商品信息。
因此思路是在擴展類ItemsQueryVo中新添加一個List<ItemsCustom>
,而後將不一樣商品的信息都存到這個List中,因此修改以下:
controller方法的定義:
一、進入批量商品修改頁面
二、批量修改商品提交
因此controller中應該有兩個方法,以下:
前臺jsp頁面中是如何傳入參數的呢?這是咱們所關心的問題,由於後臺形參中接收數據用的就是包裝類ItemsQueryVo。看下面:
因此咱們知道了,前臺是經過相似於list[i].name這種形式來傳遞參數的。list[i]表示第i個ItemsCustom,而後 list[i].屬性 表示第i個ItemsCustom中對應的屬性。
Map的綁定其實和List的綁定是差很少的,首先也是在包裝的pojo中新添加一個Map類型的屬性,如(我隨便舉個例子,跟本例無關了)
Public class QueryVo { private Map<String, Student> itemInfo = new HashMap<String, Student>(); //get/set方法.. }
關鍵是前臺傳參的時候和List不太同樣,Map是這樣傳的,好比:
<tr> <td>學生信息:</td> <td> 姓名:<input type="text" name="itemInfo['name']"/> 年齡:<input type="text" name="itemInfo['price']"/> .. .. .. </td> </tr>
咱們能夠看到,Map的參數綁定傳來的是Map中的key,而後value會自動綁定到Map中的那個對象的屬性中。在controller中的方法裏,形參就直接使用QueryVo接收便可,也很簡單。 關於springmvc的參數綁定基本就總結到這了,其實原理都差很少,只是針對於不一樣的類型,綁定的方式有些區別而已,多想一想多寫寫,基本就能掌握這些了。