天天看點

SpringMVC詳解(五)------參數綁定

SpringMVC詳解(五)------參數綁定

  參數綁定,簡單來說就是用戶端發送請求,而請求中包含一些資料,那麼這些資料怎麼到達 Controller ?這在實際項目開發中也是用到的最多的,那麼 SpringMVC 的參數綁定是怎麼實作的呢?下面我們來詳細的講解。

1、SpringMVC 參數綁定

  在 SpringMVC 中,送出請求的資料是通過方法形參來接收的。從用戶端請求的 key/value 資料,經過參數綁定,将 key/value 資料綁定到 Controller 的形參上,然後在 Controller 就可以直接使用該形參。

  

SpringMVC詳解(五)------參數綁定

  這裡涉及到參數綁定元件,那麼什麼是參數元件,這裡可以先了解為将請求的資料轉換為我們需要的資料稱為參數綁定元件,也就是參數綁定轉換器。SpringMVC 内置了很多參數轉換器,隻有在極少數情況下需要我們自定義參數轉換器。

 2、預設支援的類型

  SpringMVC 有支援的預設參數類型,我們直接在形參上給出這些預設類型的聲明,就能直接使用了。如下:

  ①、HttpServletRequest 對象

  ②、HttpServletResponse 對象

  ③、HttpSession 對象

  ④、Model/ModelMap 對象 

  Controller 代碼:

@RequestMapping("/defaultParameter")
	public ModelAndView defaultParameter(HttpServletRequest request,HttpServletResponse response,
							HttpSession session,Model model,ModelMap modelMap) throws Exception{
		request.setAttribute("requestParameter", "request類型");
		response.getWriter().write("response");
		session.setAttribute("sessionParameter", "session類型");
		//ModelMap是Model接口的一個實作類,作用是将Model資料填充到request域
		//即使使用Model接口,其内部綁定還是由ModelMap來實作
		model.addAttribute("modelParameter", "model類型");
		modelMap.addAttribute("modelMapParameter", "modelMap類型");
		
		ModelAndView mv = new ModelAndView();
		mv.setViewName("view/success.jsp");
		return mv;
	}
      

  表單代碼:(截取主要代碼)

<body>
	request:${requestParameter}
	session:${sessionParameter}
	model:${modelParameter}
	modelMap:${modelMapParameter}
</body>
      

  然後通路,頁面顯示如下:

SpringMVC詳解(五)------參數綁定

  這裡我們重點說一下 Model/ModelMap,ModelMap是Model接口的一個實作類,作用是将Model資料填充到request域,即使使用Model接口,其内部綁定還是由ModelMap來實作

 3、基本資料類型的綁定

  哪些是基本資料類型,我們這裡重新總結一下: 

一、byte,占用一個位元組,取值範圍為 -128-127,預設是“\u0000”,表示空
二、short,占用兩個位元組,取值範圍為 -32768-32767
三、int,占用四個位元組,-2147483648-2147483647
四、long,占用八個位元組,對 long 型變量指派時必須加上"L"或“l”,否則不認為是 long 型
五、float,占用四個位元組,對 float 型進行指派的時候必須加上“F”或“f”,如果不加,會産生編譯錯誤,因為系統
自動将其定義為 double 型變量。double轉換為float類型資料會損失精度。float a = 12.23産生編譯錯誤的,float a = 12是正确的
六、double,占用八個位元組,對 double 型變量指派的時候最好加上“D”或“d”,但加不加不是硬性規定 
七、char,占用兩個位元組,在定義字元型變量時,要用單引号括起來
八、boolean,隻有兩個值“true”和“false”,預設值為false,不能用0或非0來代替,這點和C語言不同
      

  我們以 int 類型為例:

  JSP 頁面代碼:

<form action="basicData" method="post">
	<input name="username" value="10" type="text"/>
	<input type="submit" value="送出">
</form>
      
@RequestMapping("/basicData")
	public void basicData(int username){
		System.out.println(username);//10
	}
      

  結果是 列印出了表單裡面的 value 的值。

  注意:表單中input的name值和Controller的參數變量名保持一緻,就能完成資料綁定。那麼如果不一緻呢?我們使用 @RequestParam 注解來完成,如下:

  JSP頁面代碼不變,<input name="username">保持原樣,Controller 代碼如下

SpringMVC詳解(五)------參數綁定

  使用注解 @RequestParam ,我們可以使用任意形參,但是注解裡面的 value 屬性值要和表單的name屬性值一樣。

  問題:我們這裡的參數是基本資料類型,如果從前台頁面傳遞的值為 null 或者 “”的話,那麼會出現資料轉換的異常,就是必須保證表單傳遞過來的資料不能為null或”",是以,在開發過程中,對可能為空的資料,最好将參數資料類型定義成包裝類型,具體參見下面的例子。

4、包裝資料類型的綁定

   包裝類型如Integer、Long、Byte、Double、Float、Short,(String 類型在這也是适用的)這裡我們以 Integer 為例

  Controller 代碼為:

SpringMVC詳解(五)------參數綁定

  和基本資料類型基本一樣,不同之處在于,表單傳遞過來的資料可以為null或”",以上面代碼為例,如果表單中num為”"或者表單中無num這個input,那麼,Controller方法參數中的num值則為null。

5、POJO(實體類)類型的綁定

  User.java

package com.ys.po;

import java.util.Date;

public class User {
    private Integer id;

    private String username;

    private String sex;

    private Date birthday;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex == null ? null : sex.trim();
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
      

  JSP頁面:注意輸入框的 name 屬性值和上面 POJO 實體類的屬性保持一緻即可映射成功。

<form action="pojo" method="post">
		使用者id:<input type="text" name="id" value="2"></br>
		使用者名:<input type="text" name="username" value="Marry"></br>
		性别:<input type="text" name="sex" value="女"></br>
		出生日期:<input type="text" name="birthday" value="2017-08-25"></br>
		<input type="submit" value="送出">
	</form>
      

  注意看:這裡面我們資料都寫死了,直接送出。有Integer類型的,String類型的,Date類型的。

  Controller :

@RequestMapping("/pojo")
	public void pojo(User user){
		System.out.println(user);
	}
      

  我們在上面代碼打個斷點,然後輸入URL,進入到這個Controller中:

SpringMVC詳解(五)------參數綁定

  上面是報錯了,User.java 的birthday 屬性是 Date 類型的,而我們輸入的是字元串類型,故綁定不了

   那麼問題來了,Date 類型的資料綁定失敗,如何解決這樣的問題呢?這就是我們前面所說的需要自定義Date類型的轉換器。

  ①、定義由String類型到 Date 類型的轉換器

package com.ys.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;

//需要實作Converter接口,這裡是将String類型轉換成Date類型
public class DateConverter implements Converter<String, Date> {

	@Override
	public Date convert(String source) {
		//實作将字元串轉成日期類型(格式是yyyy-MM-dd HH:mm:ss)
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return dateFormat.parse(source);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//如果參數綁定失敗傳回null
		return null;
	}

}
      

  ②、在 springmvc.xml 檔案中配置轉換器

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
	
	<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
		<property name="converters">
			<!-- 自定義轉換器的類名 -->
			<bean class="com.ys.util.DateConverter"></bean>
		</property>
	</bean>
      

  輸入 URL,再次檢視Controller的形參:

SpringMVC詳解(五)------參數綁定

6、複合POJO(實體類)類型的綁定

  這裡我們增加一個實體類,ContactInfo.java

package com.ys.po;

public class ContactInfo {
    private Integer id;

    private String tel;

    private String address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel == null ? null : tel.trim();
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address == null ? null : address.trim();
    }
}
      

  然後在上面的User.java中增加一個屬性 private ContactInfo contactInfo

SpringMVC詳解(五)------參數綁定

  JSP 頁面:注意屬性name的命名,User.java 的複合屬性名.字段名

   

SpringMVC詳解(五)------參數綁定

      

  Controller

SpringMVC詳解(五)------參數綁定

  User對象中有ContactInfo屬性,但是,在表單代碼中,需要使用“屬性名(對象類型的屬性).屬性名”來命名input的name。

7、數組類型的綁定

  需求:我們查詢出所有User 的資訊,并且在JSP頁面周遊顯示,這時候點選送出按鈕,需要在 Controller 中獲得頁面中顯示 User 類的 id 的所有值的數組集合。

  JSP 頁面:注意使用者id的name值定義為 userId

SpringMVC詳解(五)------參數綁定

  Controller.java

SpringMVC詳解(五)------參數綁定

8、List類型的綁定

  需求:批量修改 User 使用者的資訊

  第一步:建立 UserVo.java,封裝 List<User> 屬性

package com.ys.po;

import java.util.List;

public class UserVo {
	
	private List<User> userList;
	public List<User> getUserList() {
		return userList;
	}
	public void setUserList(List<User> userList) {
		this.userList = userList;
	}
}
      

  第二步:為了簡化過程,我們直接從 Controller 中查詢所有 User 資訊,然後在頁面顯示

@RequestMapping("selectAllUserAndList")
	public ModelAndView selectAllUserAndList(){
		List<User> listUser = userService.selectAllUser();
		ModelAndView mv = new ModelAndView();
		mv.addObject("listUser", listUser);
		mv.setViewName("list.jsp");
		return mv;
	}
      

  JSP 頁面

SpringMVC詳解(五)------參數綁定

  第三步:修改頁面的值後,點選送出

SpringMVC詳解(五)------參數綁定

  由于我們在 JSP 頁面 input 輸入框定義的name屬性名是 userList[${status.index}].id 這種形式的,這裡我們直接用 UserVo 就能擷取頁面批量送出的 User資訊

8、Map類型的綁定

  首先在 UserVo 裡面增加一個屬性 Map<String,User> userMap

   

SpringMVC詳解(五)------參數綁定

  第二步:JSP頁面,注意看 <input >輸入框 name 的屬性值

SpringMVC詳解(五)------參數綁定

   第三步:Controller 中擷取頁面的屬性

SpringMVC詳解(五)------參數綁定

9、遇到的問題

  ①、form表單無法送出input輸入框屬性設定為 disabled 的内容

  比如:

<input type="text" disabled="disabled" name="metadataName"   maxlength="50" placeholder="這裡輸入模型英文名稱" title="模型英文名稱" "/>
      

  具有 disabled="disabled" 的屬性,送出到 Controller後,metadataName 的值為null

  解決辦法:改為 readonly="readonly"

  readonly:針對input(text / password)和textarea有效,在設定為true的情況下,使用者可以獲得焦點,但是不能編輯,在送出表單時,輸入項會作為form的内容送出。

  disabled:針對所有表單元素(select,button,input,textarea等),在設定為disabled為true的情況下,表單輸入項不能獲得焦點,使用者的所有操作無意義,在送出表單時,表單輸入項不會被送出。

作者:IT可樂

出處:http://www.cnblogs.com/ysocean/

資源:微信搜【IT可樂】關注我,回複 【電子書】有我特别篩選的免費電子書。

本文版權歸作者所有,歡迎轉載,但未經作者同意不能轉載,否則保留追究法律責任的權利。