SpringMVC:請求參數的綁定
- SpringMVC 綁定請求參數的過程是通過把表單提交請求參數,作爲控制器中方法參數進行綁定的。
支持的數據類型
1、基本類型參數 :
包括基本類型和 String 類型
2、POJO 類型參數 :
包括實體類,以及關聯的實體類
3、數組和集合類型參數 :
包括 List 結構和 Map 結構的集合(包括數組)
SpringMVC 綁定請求參數是自動實現的,但是要想使用,必須遵循使用要求:
1、如果是基本類型或者 String 類型:
要求我們的參數名稱必須和控制器中方法的形參名稱保持一致。(嚴格區分大小寫)
2、如果是 POJO 類型 ,或者 它的關聯對象 :
要求表單中參數名稱和 POJO 類的屬性名稱保持一致。並且控制器方法的參數類型是 POJO 類型。
3、如果是集合類型, 有兩種方式:
第一種:
要求集合類型的請求參數必須在 POJO 中。在表單中請求參數名稱要和 POJO 中集合屬性名稱相同。
給 List 集合中的元素賦值,使用下標。
給 Map 集合中的元素賦值,使用鍵值對。
第二種:
接收的請求參數是 json 格式數據。需要藉助一個註解實現。
注意:
它還可以實現一些數據類型自動轉換。如遇特殊類型轉換要求,需要我們自己編寫自定義類型轉換器。
示例代碼
基本類型以及String類型
jsp代碼
<h3>testBasicType</h3>
<a href="test/testBasicType?account=1000&userName=zhangsan">testBasicType</a>
控制器代碼
@RequestMapping(path = "/testBasicType")
public String testBasicType(Integer account,String userName){
System.out.println("HtestBasicType:account "+ account +" userName: " +userName);
return "success";
}
POJO類型
實體類代碼
public class Account implements Serializable {
private String username;
private double money;
private User user;
}
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private Date date;
}
jsp代碼
<h3>testPOJO</h3>
<form action="test/testPOJO" method="post">
username:<input type="text" name="username"><br>
money:<input type="text" name="money"><br>
address:<input type="text" name="user.address"><br>
date:<input type="text" name="user.date"><br>
<input type="submit" value="提交"><br>
</form>
控制器代碼
@RequestMapping(path = "/testPOJO")
public String testPOJOType(Account account){
System.out.println("testPOJOType:account "+ account);
return "success";
}
POJO中包含集合類型
實體類代碼
public class Account implements Serializable {
private String username;
private double money;
private List<User> list;
private Map<String,User> map;
}
jsp代碼
<h3>testList</h3>
<form action="test/testList" method="post">
username:<input type="text" name="username"><br>
money:<input type="text" name="money"><br>
用戶1 address:<input type="text" name="list[0].address"><br>
用戶1 date:<input type="text" name="list[0].date"><br>
用戶2 address:<input type="text" name="map['two'].address"><br>
用戶2 date:<input type="text" name="map['two'].date"><br>
<input type="submit" value="提交"><br>
</form>
控制器代碼
@RequestMapping(path = "/testList")
public String testList(Account account){
System.out.println("testList:account "+ account);
return "success";
}
自定義類型轉換器
第一步:定義一個類,實現 Converter 接口,該接口有兩個泛型。
public interface Converter<S, T> {//S:表示接受的類型,T:表示目標類型
/**
* 實現類型轉換的方法
*/
@Nullable
T convert(S source);
}
/**
* 自定義類型轉換器
* @author 黑馬程序員
* @Company http://www.ithiema.com
* @Version 1.0
*/
public class StringToDateConverter implements Converter<String, Date> {
/**
* 用於把 String 類型轉成日期類型
*/
@Override
public Date convert(String source) {
DateFormat format = null;
try {
if(StringUtils.isEmpty(source)) {
throw new NullPointerException("請輸入要轉換的日期");
}
format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(source);
return date;
} catch (Exception e) {
throw new RuntimeException("輸入日期有誤");
}
}
}
第二步:在 spring 配置文件中配置類型轉換器。
spring 配置類型轉換器的機制是,將自定義的轉換器註冊到類型轉換服務中去
<!-- 配置類型轉換器工廠 -->
<bean id="converterService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 給工廠注入一個新的類型轉換器 -->
<property name="converters">
<array>
<!-- 配置自定義類型轉換器 -->
<bean class="com.itheima.web.converter.StringToDateConverter"></bean>
</array>
</property>
</bean>
第三步:在 annotation-driven 標籤中引用配置的類型轉換服務
<!-- 引用自定義類型轉換器 -->
<mvc:annotation-driven
conversion-service="converterService"></mvc:annotation-driven>
使用 ServletAPI
SpringMVC 還支持使用原始 ServletAPI 對象作爲控制器方法的參數。支持原始 ServletAPI 對象有:
HttpServletRequest
HttpServletResponse
HttpSession
java.security.Principal
Locale
InputStream
OutputStream
Reader
Writer
我們可以把上述對象,直接寫在控制的方法參數中使用。
jsp代碼
<!-- 原始 ServletAPI 作爲控制器參數 -->
<a href="account/testServletAPI">測試訪問 ServletAPI</a>
控制器中的代碼:
@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";
}
請求參數亂碼問題
post 請求方式:
在 web.xml 中配置一個過濾器
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在 springmvc 的配置文件中可以配置,靜態資源不過濾:
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
<mvc:resources location="/scripts/" mapping="/javascript/**"/>
get 請求方式:
tomacat 對 GET和 POST 請求處理方式是不同的,GET請求的編碼問題,要改 tomcat 的 server.xml
配置文件,如下:
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"/>
改爲:
<Connector connectionTimeout="20000" port="8080"
protocol="HTTP/1.1" redirectPort="8443"
useBodyEncodingForURI="true"/>
如果遇到 ajax 請求仍然亂碼,請把:
useBodyEncodingForURI="true"改爲 URIEncoding="UTF-8"