請求數據傳入
1. 請求處理方法簽名
Spring MVC 通過分析處理方法的簽名,HTTP請求信息綁定到處理方法的相應人蔘中。
Spring MVC 對控制器處理方法簽名的限制是很寬鬆的,幾乎可以按喜歡的任何方式對方法進行簽名。
必要時可以對方法及方法入參標註相應的註解( @PathVariable 、@RequestParam、@RequestHeader 等)、
Spring MVC 框架會將 HTTP 請求的信息綁定到相應的方法入參中,並根據方法的返回值類型做出相應的後續處理。
2. @RequestParam註解
在處理方法入參處使用 @RequestParam 可以把請求參數傳遞給請求方法
value:參數名
required:是否必須。默認爲 true, 表示請求參數中必須包含對應的參數,若不存在,將拋出異常
defaultValue: 默認值,當沒有傳遞參數時使用該值
3. 實驗代碼
① 增加控制器方法
/**
* @RequestParam 註解用於映射請求參數
* value 用於映射請求參數名稱
* required 用於設置請求參數是否必須的
* defaultValue 設置默認值,當沒有傳遞參數時使用該值
*/
@RequestMapping(value="/testRequestParam")
public String testRequestParam(
@RequestParam(value="username") String username,
@RequestParam(value="age",required=false,defaultValue="0") int age){
System.out.println("testRequestParam - username="+username +",age="+age);
return "success";
}
② 增加頁面鏈接
<!--測試 請求參數 @RequestParam 註解使用 -->
<a href="springmvc/testRequestParam?username=atguigu&age=10">testRequestParam</a>
4. @RequestHeader 註解
使用 @RequestHeader 綁定請求報頭的屬性值
請求頭包含了若干個屬性,服務器可據此獲知客戶端的信息,通過 @RequestHeader 即可將請求頭中的屬性值綁定到處理方法的入參中
5. 實驗代碼
//瞭解: 映射請求頭信息 用法同 @RequestParam
@RequestMapping(value="/testRequestHeader")
public String testRequestHeader(@RequestHeader(value="Accept-Language") String al){
System.out.println("testRequestHeader - Accept-Language:"+al);
return "success";
}
<!-- 測試 請求頭@RequestHeader 註解使用 -->
<a href="springmvc/testRequestHeader">testRequestHeader</a>
6. @CookieValue 註解
使用 @CookieValue 綁定請求中的 Cookie 值
@CookieValue 可讓處理方法入參綁定某個 Cookie 值
7. 實驗代碼
① 增加控制器方法
//瞭解:@CookieValue: 映射一個 Cookie 值. 屬性同 @RequestParam
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID") String sessionId) {
System.out.println("testCookieValue: sessionId: " + sessionId);
return "success";
}
② 增加頁面鏈接
<!--測試 請求Cookie @CookieValue 註解使用 -->
<a href="springmvc/testCookieValue">testCookieValue</a>
8. 使用POJO作爲參數
使用 POJO 對象綁定請求參數值
Spring MVC 會按請求參數名和 POJO 屬性名進行自動匹配,自動爲該對象填充屬性值。支持級聯屬性。如:dept.deptId、dept.address.tel 等
9. 實驗代碼
① 增加控制器方法、表單頁面
/**
* Spring MVC 會按請求參數名和 POJO 屬性名進行自動匹配, 自動爲該對象填充屬性值。
* 支持級聯屬性
* 如:dept.deptId、dept.address.tel 等
*/
@RequestMapping("/testPOJO")
public String testPojo(User user) {
System.out.println("testPojo: " + user);
return "success";
}
<!-- 測試 POJO 對象傳參,支持級聯屬性 -->
<form action=" testPOJO" method="POST">
username: <input type="text" name="username"/><br>
password: <input type="password" name="password"/><br>
email: <input type="text" name="email"/><br>
age: <input type="text" name="age"/><br>
city: <input type="text" name="address.city"/><br>
province: <input type="text" name="address.province"/>
<input type="submit" value="Submit"/>
</form>
② 增加實體類
package com.atguigu.springmvc.entities;
public class Address {
private String province;
private String city;
//get/set
}
package com.atguigu.springmvc.entities;
public class User {
private Integer id ;
private String username;
private String password;
private String email;
private int age;
private Address address;
//get/set
}
③ 執行結果:
④ 如果中文有亂碼,需要配置字符編碼過濾器,且配置其他過濾器之前,
如(HiddenHttpMethodFilter),否則不起作用。(思考method=”get”請求的亂碼問題怎麼解決的)配置Tomcat的配置文件
<!-- 配置字符集 -->
<filter>
<filter-name>encodingFilter</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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
10. 使用Servlet原生API作爲參數
MVC 的 Handler 方法可以接受哪些 ServletAPI 類型的參數
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
源碼參考:AnnotationMethodHandlerAdapter L866
@Override
protected Object resolveStandardArgument(Class<?> parameterType, NativeWebRequest webRequest) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
if (ServletRequest.class.isAssignableFrom(parameterType) ||
MultipartRequest.class.isAssignableFrom(parameterType)) {
Object nativeRequest = webRequest.getNativeRequest(parameterType);
if (nativeRequest == null) {
throw new IllegalStateException(
"Current request is not of type [" + parameterType.getName() + "]: " + request);
}
return nativeRequest;
}
else if (ServletResponse.class.isAssignableFrom(parameterType)) {
this.responseArgumentUsed = true;
Object nativeResponse = webRequest.getNativeResponse(parameterType);
if (nativeResponse == null) {
throw new IllegalStateException(
"Current response is not of type [" + parameterType.getName() + "]: " + response);
}
return nativeResponse;
}
else if (HttpSession.class.isAssignableFrom(parameterType)) {
return request.getSession();
}
else if (Principal.class.isAssignableFrom(parameterType)) {
return request.getUserPrincipal();
}
else if (Locale.class.equals(parameterType)) {
return RequestContextUtils.getLocale(request);
}
else if (InputStream.class.isAssignableFrom(parameterType)) {
return request.getInputStream();
}
else if (Reader.class.isAssignableFrom(parameterType)) {
return request.getReader();
}
else if (OutputStream.class.isAssignableFrom(parameterType)) {
this.responseArgumentUsed = true;
eturn response.getOutputStream();
}
else if (Writer.class.isAssignableFrom(parameterType)) {
this.responseArgumentUsed = true;
return response.getWriter();
}
return super.resolveStandardArgument(parameterType, webRequest);
}
11. 實驗代碼
/**
* 可以使用 Serlvet 原生的 API 作爲目標方法的參數 具體支持以下類型
*
* HttpServletRequest
* HttpServletResponse
* HttpSession
* java.security.Principal
* Locale InputStream
* OutputStream
* Reader
* Writer
* @throws IOException
*/
@RequestMapping("/testServletAPI")
public void testServletAPI(HttpServletRequest request,HttpServletResponse response, Writer out) throws IOException {
System.out.println("testServletAPI, " + request + ", " + response);
out.write("hello springmvc");
//return "success";
}
<!-- 測試 Servlet API 作爲處理請求參數 -->
<a href="springmvc/testServletAPI">testServletAPI</a>