springmvc學習筆記(常用注解)
1. @Controller
@Controller
注解用於表示一個類的實例是頁面控制器(后面都將稱為控制器). 使用@Controller
注解定義的控制器有如下特點:
- 不需要繼承任何類, 也不需要實現任何接口
- 可以處理多個請求
- 可以使用Servlet的相關特性
spring自動掃描所有基於注解的類, 並將其注冊為spring的bean, DispatcherServlet
自動掃描注解為@Controller
的類, 查找其中使用了@RequestMapping
的方法, 這些方法是真正處理請求方法.
<!-- 掃描包路徑com.lizj.controller下的所有類, 將帶有注解的類注冊到spring容器中 -->
<context:component-scan base-package="com.lizj.controller" />
<!-- 視圖解釋器 -->
<!-- 配置的視圖解析器為InternalResourceViewResolver, 並為其添加了前綴prefix和后綴suffix屬性 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前綴 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 后綴 -->
<property name="suffix" value=".jsp" />
</bean>
此示例中沒有配置處理映射器和處理器適配器, spring將使用默認的處理映射器和處理器適配器來處理請求.
下面是使用@Controller
注解定義的控制器
/**
* 基於注解的控制器
*/
@Controller
public class HelloController {
}
2. @RequestMapping
2.1 @RequestMapping注解
@RequestMapping
注解用來表示請求具體由哪個類的哪個方法來處理. 即
@RequestMapping
既可以用來注解一個類, 也可以用來注解一個方法. 當用來注解一個類的時候, 所有方法都將映射為相對於類級的請求.
/**
* 基於注解的控制器
*/
@Controller
public class HelloController {
@RequestMapping("/hello")
public String sayHello(HttpServletRequest request) {
model.addAttribute("message", "Hello World");
return "helloworld";
}
}
@RequestMapping
注解支持的屬性
屬性 | 類型 | 是否必要 | 說明 |
---|---|---|---|
name | String | 否 | 映射地址別名, 一般不設置 |
value | String[] | 否 | 指定請求的地址映射到方法上 |
method | RequestMethod[] | 否 | 請求的方法類型, 包括GET,POST,HEAD,OPTIONS,PUT,PATCH,DELETE,TRACE |
consumes | String[] | 否 | 指定處理請求的提交內容類型(Content-Type),例如application/json |
produces | String[] | 否 | 指定返回的內容類型, 返回的內容類型必須是request請求頭(Accept)中包含的類型 |
params | String[] | 否 | 指定request中必須包含某些參數值時, 此方法才處理此請求 |
header | String[] | 否 | 指定request中必須包含某些指定的header值, 此方法才處理此請求 |
path | String[] | 否 | In a Servlet environment... 就是value屬性的別名, value屬性沒有含義不確切, path含義更明確 |
常用的@RequestMapping
屬性:
- value
value屬性用於將請求映射到方法上. value屬性是@RequestMapping
的默認屬性, 當只有唯一的屬性時, 則可以省略屬性名, 如下兩個注解含義是一樣的:
@RequestMapping("/user")
@RequestMapping(value="/user")
多個請求地址映射到同一個方法
@RequestMapping(value={"/user", "/customer"})
- method
method屬性指定此方法只處理哪些HTTP請求. 例如:
// 此方法只處理POST請求.
@RequestMapping(value="/user", method=RequestMethod.POST)
// 此方法既支持POST請求, 又支持GET請求
@RequestMapping(value="/user", method={RequestMethod.POST,RequestMethod.GET})
如果沒有配置method屬性, 則此方法可以處理任意的HTTP請求.
兩個示例:
-
示例類: com.lizj.controller_01.HelloController01
訪問地址: http://127.0.0.1:8080/springmvc03/hello -
示例類: com.lizj.controller_01.HelloController02
訪問地址: http://127.0.0.1:8080/springmvc03/hello/hello
2.2 支持的方法參數類型
每個請求處理方法都可以有多個參數, 參數類型可以為以下類型, 可根據需要添加方法聲明參數.
javax.servlet.ServletRequest
或javax.servlet.http.HttpServletRequest
javax.servlet.ServletResponse
或javax.servlet.http.HttpServletResponse
javax.servlet.http.HttpSession
org.springframework.web.context.request.WebRequest
或org.springframework.web.context.request.NativeWebRequeset
java.util.Locale
java.io.InputStream
或java.io.Reader
用於訪問請求正文, 這兩個對象與通過Servlet API
拿到的InputSteam和Reader對象是一樣的java.io.OutputSteam
或java.io.Writer
用於生成響應正文, 這兩個對象與通過Servlet API
拿到的OutputSteam和Writer對象是一樣的java.security.Principal
包裝了當前被誰的用戶信息org.springframework.http.HttpEntity<T>
其提供了對HTTP請求頭和請求內容的存取org.springframework.web.servlet.mvc.support.RedirectAttributes
用以指定重定向下要使用到的屬性集以及添加flash屬性(暫存在服務端的屬性,它們會在下次重定向請求的范圍中有效)org.springframework.validation.Errors
或org.springframework.validation.BindingResult
驗證結果對象,用於存儲前面的命令或表單對象的驗證結果(緊接其前的第一個方法參數)org.springframework.web.bind.support.SessionStatus
用以標記當前的表單處理已結束org.springframework.web.util.UriComponentsBuilder
構造器對象, 用於構造當前請求URL相關的信息, 比如主機名、端口號、資源類型(scheme)、上下文路徑、servlet映射中的相對部分(literal part)等@PathVariable
@MatrixVariable
java.util.Map
或org.springframework.io.Model
或org.springframework.ui.ModelMap
用以增強默認暴露給視圖層的模型(model)的功能- 帶有
@RequestParam
注解的參數, 其存放了Servlet請求中所指定的參數. 參數的值會被轉換成方法參數所聲明的類型 - 帶有
@RequestHeader
注解的參數, 其存放了Servlet請求中所指定的HTTP請求頭的值. 參數的值會被轉換成方法參數所聲明的類型 - 帶有
@RequestBody
注解的參數, 提供了對HTTP請求體的存取. 參數的值通過HttpMessageConverter
被轉換成方法參數所聲明的類型 - 帶有
@RequestPart
注解的參數, 提供了對一個"multipart/form-data請求塊(request part)內容的存取 - 命令或表單對象, 它們用於將請求參數直接綁定到bean字段(可能是通過setter方法)
在參數列表中,
Errors
或BindingResult
參數必須緊跟在其所綁定的驗證對象后面. 這是因為, 在參數列表中允許有多於一個的模型對象, spring會為它們創建不同的BindingResult實例
所有方法參數中, 最重要的是org.springframework.ui.Model
, 它是一個接口, 功能類似於java.util.Map
, 用於存儲模型數據. springmvc調用處理方法前, 會創建一個隱含的模型對象, 作為模型數據的存儲容器. 如果處理方法的方法參數為Model
, 那么springmvc會將模型的引用傳遞給此參數. 那么在方法內部就可以訪問模型中的數據, 也可以向模型中添加新的屬性數據.
/*
* springmvc中controller中的方法參數, 支持大多數常用的數據類型,
* 如: String, int....
*/
// 需要注意的是, 此處請求參數名必須與方法參數名一致, 否則獲取不到參數值, 后面@RequestParam再做詳細解釋
@RequestMapping("/get")
public String getUser(String id, Model model) {
User user = null;
for(int i=0; i<userList.size(); i++) {
User u = userList.get(i);
if(u.getId().equals(id)) {
user = u;
break ;
}
}
if(user == null) {
user = new User();
user.setId("001");
user.setName("張三");
user.setAge(18);
user.setSex("男");
}
// 向model中添加數據
model.addAttribute("user", user);
// 返回視圖名稱
return "user/oneuser";
}
兩個示例:
-
示例類: com.lizj.controller_02.UserController01
訪問地址: http://127.0.0.1:8080/springmvc003/user01/get -
示例類: com.lizj.controller_02.UserController02
訪問地址: http://127.0.0.1:8080/springmvc003/user02/get?userId=2
2.3 支持的方法返回類型
請求處理方法的返回類型如下:
org.springframework.web.servlet.ModelAndView
org.springframework.ui.Model
java.util.Map<K, V>
org.springframework.web.servlet.View
java.lang.String
HttpEntity<?>
或ResponseEntity<?>
java.util.concurrent.Callable
org.springframework.web.context.request.async.DeferredResult<?>
void
如果控制器處理方法的返回值是ModelAndView
類型, 其既包括模型數據, 又包括視圖信息, 那么springmvc就可以使用包含的視圖對模型數據進行渲染, 而且可以非常方便的訪問模型數據. ModelAndview
對象常用的添加模型數據和設置視圖的方法如下:
// 添加模型數據
addObject(String attributeName, Object attributeValue);
// 設置視圖
setViewName(String viewName);
示例類: com.lizj.controller_02.UserController03
訪問地址: http://127.0.0.1:8080/springmvc003/user03/get?userId=3
3. @RequestParam
@RequestParam
注解用於將指定的請求參數賦值給方法的參數.
@RequestParam
注解支持的屬性
屬性 | 類型 | 是否必要 | 說明 |
---|---|---|---|
name | String | 否 | 指定請求參數綁定的名稱 |
value | String | 否 | name屬性的別名 |
required | boolean | 否 | 指示參數是否必須綁定 |
default | String | 否 | 沒有參數時使用的默認值 |
請求處理的方法的參數的類型為Java基本類型和String.
@RequestMapping(value="/add", method=RequestMethod.POST)
public String add(@RequestParam("name") String name,
@RequestParam("author") String author) {
}
當方法參數沒有用
@RequestParam
修飾時, 那么會默認綁定同名的參數.
示例類: com.lizj.controller_03.BookController
訪問地址: http://127.0.0.1:8080/springmvc003/book/books
4. @PathVariable
@PathVariable
注解可以方便的從URL中獲取請求的參數.
它只支持一個類型為String
的屬性, 表示綁定的請求參數的名稱, 省略則默認綁定同名的參數.
@RequestMapping(value="/book/{bookId}")
public ModelAndView get(@PathVariable int bookId)
示例類: com.lizj.controller_04.BookController04
訪問地址: http://127.0.0.1:8080/springmvc003/book04/books
5. @RequestHeader
@RequestHeader
注解用於將請求的頭信息區數據映射到請求處理方法的參數上.
@RequestHeader
注解支持的屬性
屬性 | 類型 | 是否必要 | 說明 |
---|---|---|---|
name | String | 否 | 指定請求頭綁定的名稱 |
value | String | 否 | name屬性的別名 |
required | boolean | 否 | 指示參數是否必須綁定 |
default | String | 否 | 沒有參數時使用的默認值 |
public void testRequestHeader(
@RequestHeader("User-Agent") String userAgent,
@RequestHeader("Accept") String[] accepts) {
// ...
}
示例類: com.lizj.controller_05.HeaderAndCookieController
訪問地址: http://localhost:8080/springmvc003/hac/show
關於http請求的header頭信息
參考: http://www.cnblogs.com/printN/p/6534529.html
6. @CookieValue
@CookieValue
注解將Cookie數據映射到請求處理方法的參數上.
@CookieValue
注解支持的屬性
屬性 | 類型 | 是否必要 | 說明 |
---|---|---|---|
name | String | 否 | 指定請求頭綁定的名稱 |
value | String | 否 | name屬性的別名 |
required | boolean | 否 | 指示參數是否必須綁定 |
default | String | 否 | 沒有參數時使用的默認值 |
示例類: com.lizj.controller_05.HeaderAndCookieController
訪問地址: http://localhost:8080/springmvc003/hac/show
7. @SessionAttributes
@SessionAttributes
注解指定Model
中哪些數據需要轉存到session
中.
@SessionAttributes
注解支持的屬性
屬性 | 類型 | 是否必要 | 說明 |
---|---|---|---|
names | String[] | 否 | Model中屬性的名稱, 儲存在session中也會用此名稱 |
values | String[] | 否 | names屬性的別名 |
types | Class<?>[] | 否 | 根據指定參數的類型, 將模型中對應類型的參數存儲到session中 |
@SessionAttributes
注解只能聲明在類上, 不能聲明在方法上.
示例類: com.lizj.controller_06.LoginController
訪問地址: http://localhost:8080/springmvc003/login
8. @ModelAttribute
@ModelAttribute
注解用於將請求參數綁定到Model對象上.
@ModelAttribute
只支持一個類型為String
的屬性value
, 表示綁定的屬性名稱.
需要注意的是, @ModelAttribute
注解修飾的方法會在Controller
的每個請求處理方法執行前被執行, 如果一個Controller
映射了多個URL要注意這一問題.
示例類: com.lizj.controller_06.PageController
訪問地址: http://127.0.0.1:8080/springmvc003/mac/testPage
可結合示例, 閱讀下面幾種情況的介紹.
@ModelAttribute
注解修飾的方法有返回值
示例:
@ModelAttribute("paramName")
public String getParam(@RequestParam("param") String param) {
return param;
}
此方法將先於其他請求處理方法執行, 並且將請求參數param
的值, 以paramName
為名稱, 指定為model
的一個屬性, 此時model
並沒有顯示的定義出來.
示例:
@ModelAttribute
// 這次沒有使用@ModelAttribute注解的value屬性
public User getUserById(String userId) {
return userService.getUserById(userId);
}
示例中沒有顯示的使用
@RuquestParam
注解, 而是使用了默認綁定同名參數.
本示例中, 方法的返回值類型為User
, 且沒有使用@ModelAttribute
注解的value
屬性. 此時, value
的默認名稱為方法返回值類型(首字母小寫), 即模型中的屬性名為方法返回值類型(首字母小寫). 也可以顯示的定義value
屬性.
@ModelAttribute
注解修飾的方法有返回值, 返回值類型為void
示例:
@ModelAttribute
public void getUserById(String userId, Model model) {
model.addAttribute("user", userService.getUserById(userId));
}
這種寫法的前提是在請求處理方法中加入了一個Model
參數.
@ModelAttribute
和@RequestMapping
修飾同一個方法
示例:
@RequestMapping("/show")
@ModelAttribute("username")
public String show(String userId) {
User user = userService.getUserById(userId);
return user.getName();
}
示例中, @ModelAttribute
和@RequestMapping
共同修飾了show
方法. 此時方法的返回值不再是視圖名稱, 而是Model
的屬性值, Model
屬性的名稱由@ModelAttribute
的value
設置, 即username
;
而@RequestMapping
的value
值/show
除了是請求映射之外, 還將作為視圖名稱, 即此請求處理方法將跳轉至名稱為show
的頁面.
@ModelAttribute
修飾一個請求處理方法的參數
示例:
@ModelAttribute
public User getUserById(String userId) {
return userService.getUserById(userId);
}
@RequestMapping("/show")
public String show(@ModelAttribute User user) {
return "mac/test05";
}
示例中, @ModelAttribute
修飾的getUserById()
方法仍舊在Model
中添加user
屬性, 其值為一個User
對象.
而在show
方法中, 參數也被@ModelAttribute
修飾, 表示參數user
的值就是Model
中的屬性值.
9. @RequestBody 和 @ResponseBody
9.1 @RequestBody
springmvc提供了處理JSON格式請求和響應的功能, 可以方便的使服務端的請求處理方法和客戶端JSON格式消息進行交互, 這時就用到了@RequestBody
注解.
@RequestBody
注解用於讀取request請求的body部分的數據, 解析后, 把相應的數據綁定到請求處理方法的參數上.
前台頁面使用GET或POST請求提交數據時, 數據編碼格式會由請求頭的
ContentType
來指定, 可分為以下幾種情況:
- application/x-www-form-urlencoded, 此時可以使用
@RequestParam
,@ModelAttribute
來處理參數, 也可以使用@RequestBody
.- multipart/form-data, 此時不能使用
@RequestBody
處理.- application/json或application/xml, 只能使用
@RequestBody
處理.
9.2 @ResponseBody
@ResponseBody
注解用於將Controller
的請求處理方法返回的數據對象, 轉換為指定格式后, 寫入到response對象的的body數據區. 一般地, 返回的數據不是某個具體的視圖頁面, 而是某種格式的數據(json, xml等).
9.3 示例
示例類: springmvc004項目中, com.lizj.controller_08.BookController08
訪問地址: http://127.0.0.1:8080/springmvc004/book08/books
簡單說明:
9.3.1 springmvc-servlet.xml
springmvc-servlet.xml配置文件中, 添加加了兩項配置:
<!-- 自動注冊RequestMappingHandlerMapping和RequestMappingHandlerAdapter -->
<mvc:annotation-driven />
<!-- DispatcherServlet會攔截所有請求, 會將靜態文件(如js文件)的請求看成路徑, 就會找不到對應的靜態文件 -->
<!-- 此配置將使用默認的servlet響應靜態文件, 避免出現上述情況 -->
<mvc:default-servlet-handler/>
springmvc4.x默認使用的HandlerMapping和HandlerAdapter為:
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
詳情見:
spring-webmvc-4.2.3.RELEASE.jar
org.springframework.web.servlet包下的DispatcherServlet.properties文件.
9.3.2 pom.xml
引用Jackson
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.2</version>
</dependency>
Jackson用來實現json對象與Java對象之間的轉換.
示例下載:
https://files.cnblogs.com/files/lzj0616/springmvc常用注解示例.rar