請(qǐng)求參數(shù)的綁定
一废封、一般的參數(shù)綁定
1). 綁定的機(jī)制
表單中請(qǐng)求參數(shù)都是基于key=value的窒所。SpringMVC綁定請(qǐng)求參數(shù)的過(guò)程是通過(guò)把表單提交的請(qǐng)求參數(shù)作為控制器中方法參數(shù)進(jìn)行綁定的躬窜。
- 例如,有一個(gè)超鏈接,其中請(qǐng)求參數(shù)是
accountId=10
<a href="account/findAccount?accountId=10">查詢賬戶</a>
- 對(duì)應(yīng)的控制器(只展示二級(jí)訪問(wèn)目錄)
@RequestMapping("/findAccount")
public String findAccount(Integer accountId) {
System.out.println("查詢了賬戶。做修。脚猾。葱峡。" + accountId);
return "success";
}
2). 支持的數(shù)據(jù)類型及使用規(guī)則
SpringMVC綁定請(qǐng)求參數(shù)是框架底層自動(dòng)實(shí)現(xiàn)的。
1. 基本類型參數(shù):【基本類型】 + 【String】
要求參數(shù)名稱必須和控制器中方法的形參名稱保持一致龙助。嚴(yán)格區(qū)分大小寫(xiě)
- jsp代碼
<a href="account/findAccount?accountId=10&accountName=zhangsan">查詢賬戶</a>
- 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {
/** 查詢賬戶 */
@RequestMapping("/findAccount")
public String findAccount(Integer accountId, String accountName) {
System.out.println("查詢了賬戶:" + accountId + " 姓名:" + accountName);
return "success";
}
}
2. POJO:【實(shí)體類】 + 【關(guān)聯(lián)的實(shí)體類】
表單中參數(shù)名稱和pojo類的屬性名稱保持一致砰奕,并且控制器方法的參數(shù)類型是POJO類型。
- 實(shí)體類代碼
public class Account implements Serializable {
private Integer id;
private String name;
private Float money;
private Address address;
...get/set/toString/構(gòu)造函數(shù)...
/*- - - - - - - - - - - - - - - - - - */
public class Address implements Serializable {
private String provinceName;
private String cityName;
...get/set/toString/構(gòu)造函數(shù)...
- jsp標(biāo)簽
<form action="account/saveAccount" method="post">
賬戶名稱: <input type="text" name="name"> <br>
賬戶金額: <input type="text" name="money"> <br>
賬戶省份: <input type="text" name="address.provinceName"> <br>
賬戶城市: <input type="text" name="address.cityName"> <br>
<input type="submit" value="保存">
</form>
- 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {
/** 保存賬戶 */
@RequestMapping("saveAccount")
public String saveAccount(Account account) {
System.out.println(account);
return "success";
}
}
3. 數(shù)組和集合類型:【基本數(shù)組】 + 【List】 + 【Map】
有兩種方式提鸟,如下
1. 方式一:POJO類中包含集合類型參數(shù)
要求集合類型的請(qǐng)求參數(shù)必須在POJO中军援。在表單中請(qǐng)求參數(shù)名稱和POJO中集合屬性名稱相同。
給List集合中的元素賦值沽一,使用下標(biāo)盖溺。
給Map集合中的元素賦值,使用鍵值對(duì)铣缠。
- pojo相關(guān)類User
public class User implements Serializable {
private String username;
private String password;
private Integer age;
private List<Account> accounts;
private Map<String, Account> accountMap;
... get/set/toString ...
- jsp代碼
<form action="account/updateAccount" method="post">
用戶名稱:<input type="text" name="username"> <br>
用戶密碼:<input type="password" name="password"> <br>
用戶年齡:<input type="text" name="age"> <br>
<%-- List --%>
賬戶1名稱:<input type="text" name="accounts[0].name"> <br>
賬戶1金額: <input type="text" name="accounts[0].money"> <br>
賬戶1省份:<input type="text" name="accounts[0].address.provinceName"> <br>
賬戶1城市: <input type="text" name="accounts[0].address.cityName"> <br>
<%-- Map --%>
賬戶2名稱:<input type="text" name="accountMap['one'].name"> <br>
賬戶2金額:<input type="text" name="accountMap['one'].money"> <br>
賬戶2省份:<input type="text" name="accountMap['one'].address.provinceName"> <br>
賬戶2城市:<input type="text" name="accountMap['one'].address.cityName"> <br>
<input type="submit" value="保存">
</form>
- 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {
/** 更新賬戶 */
@RequestMapping("/updateAccount")
public String updateAccount(User user) {
System.out.println(user);
return "success";
}
}
2. 方式二:JSON
接收的請(qǐng)求參數(shù)是json格式數(shù)據(jù)烘嘱。需要借助一個(gè)注解實(shí)現(xiàn)昆禽。
4. 數(shù)據(jù)類型的自動(dòng)轉(zhuǎn)換
內(nèi)置轉(zhuǎn)換器全在
org.springframework.core.converter.support
包下。內(nèi)置的轉(zhuǎn)換規(guī)則如下:
原始數(shù)據(jù)類型 | ->轉(zhuǎn)換后的類型以及對(duì)應(yīng)的轉(zhuǎn)換器 |
---|---|
java.lang.Boolean -> | java.lang.String : ObjectToStringConverter |
java.lang.Character -> | java.lang.Number : CharacterToNumberFactory |
java.lang.Character -> | java.lang.String : ObjectToStringConverter |
java.lang.Enum -> | java.lang.String : EnumToStringConverter |
java.lang.Number -> | java.lang.Character : NumberToCharacterConverter |
java.lang.Number -> | java.lang.Number : NumberToNumberConverterFactory |
java.lang.Number -> | java.lang.String : ObjectToStringConverter |
java.lang.String -> | java.lang.Boolean : StringToBooleanConverter |
java.lang.String -> | java.lang.Character : StringToCharacterConverter |
java.lang.String -> | java.lang.Enum : StringToEnumConverterFactory |
java.lang.String -> | java.lang.Number : StringToNumberConverterFactory |
java.lang.String -> | java.util.Locale : StringToLocaleConverter |
java.lang.String -> | java.util.Properties : StringToPropertiesConverter |
java.lang.String -> | java.util.UUID : StringToUUIDConverter |
java.util.Locale -> | java.lang.String : ObjectToStringConverter |
java.util.Properties -> | java.lang.String : PropertiesToStringConverter |
java.util.UUID -> | java.lang.String : ObjectToStringConverter |
... | ... |
如果遇到特殊類型轉(zhuǎn)換需求蝇庭,需要自己編寫(xiě)自定義類型轉(zhuǎn)換器醉鳖。
二、自定義類型轉(zhuǎn)換器綁定參數(shù)
以String轉(zhuǎn)為Date為例
1). 定義一個(gè)類哮内,實(shí)現(xiàn)Converter接口盗棵,該接口有兩個(gè)泛型
- Converter接口的源碼!【可千萬(wàn)別自己寫(xiě)北发,必須的使用Spring提供的Converter接口】
/** 實(shí)現(xiàn)Converter接口纹因,該接口有兩個(gè)泛型,
* S代表接收的類型琳拨,T代表目標(biāo)類型 */
public interface Converter<S, T> {
/** 實(shí)現(xiàn)類型轉(zhuǎn)換的方法 */
T convert(S source);
}
- 實(shí)現(xiàn)類StringToDateConverter
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.StringUtils;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
public class StringToDateConverter implements Converter<String, Date> {
/** 將String類型轉(zhuǎn)換成日期類型 */
@Override
public Date convert(String source) {
DateFormat format = null;
try {
if (StringUtils.isEmpty(source)) {
throw new NullPointerException("請(qǐng)輸入要轉(zhuǎn)換的日期");
}
format = new SimpleDateFormat("yyyy-MM-dd");
return format.parse(source);
} catch (Exception e) { throw new RuntimeException(e); }
}
}
2). 在spring配置文件springMVC.xml中配置自定義類型轉(zhuǎn)換器
spring配置類型轉(zhuǎn)換器的機(jī)制是將自定義的轉(zhuǎn)換器注冊(cè)到類型轉(zhuǎn)換服務(wù)中去瞭恰。
<!-- 配置類型轉(zhuǎn)換工廠 -->
<bean id="converterService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 給工廠注入一個(gè)新的類型轉(zhuǎn)化器 -->
<property name="converters">
<array>
<!-- 配置自定義類型轉(zhuǎn)換器 -->
<bean class="com.itheima.converter.impl.StringToDateConverter"></bean>
</array>
</property>
</bean>
3). 在<annotation-driven>
標(biāo)簽中應(yīng)用配合的類型轉(zhuǎn)換服務(wù)
<!-- 配置spring開(kāi)啟注解mvc的支持,并引用自定義類型轉(zhuǎn)換器 -->
<mvc:annotation-driven
conversion-service="converterService"></mvc:annotation-driven>
4). 測(cè)試代碼
- jsp核心代碼
<%-- 特殊情況值:類型轉(zhuǎn)換問(wèn)題狱庇! --%>
<a href="account/deleteAccount?date=2019-01-01">根據(jù)日期刪除賬戶</a>
- 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {
/** 刪除賬戶 */
@RequestMapping("/deleteAccount")
public String deleteAccount(Date date) {
System.out.println(date);
return "success";
}
}
三惊畏、 使用ServletAPI對(duì)象作為方法參數(shù)
SpringMVC還支持使用原始ServletAPI對(duì)象作為控制器方法的參數(shù)。可以將這些對(duì)象直接寫(xiě)在控制的方法參數(shù)中并使用
支持原始Servlet的對(duì)象 |
---|
HttpServletRequest |
HttpServletResponse |
HttpSession |
java.security.Principal |
Locale |
InputStream |
OutputStream |
Reader |
Writer |
). 實(shí)例代碼
- jsp核心代碼
<%-- 原始ServletAPI作為控制器參數(shù) --%>
<a href="account/testServletAPI">測(cè)試訪問(wèn)ServletAPI</a>
- 控制器代碼
@Controller
@RequestMapping("/account")
public class AccountController {
/** 測(cè)試訪問(wèn)testServletAPI */
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request,
HttpServletResponse response,
HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "success";
}
}