6.1、註解式控制器簡介
一、Spring2.5之前,我們都是通過實現Controller接口或其實現來定義我們的處理器類。已經@Deprecated。
二、Spring2.5引入註解式處理器支持,通過@Controller 和 @RequestMapping註解定義我們的處理器類。
並且提供了一組強大的註解:
需要通過處理器映射DefaultAnnotationHandlerMapping和處理器適配器
AnnotationMethodHandlerAdapter
來開啓支持@Controller 和
@RequestMapping註解的處理器。
@Controller:
用於標識是處理器類;
@RequestMapping:
請求到處理器功能方法的映射規則;
@RequestParam:
請求參數到處理器功能處理方法的方法參數上的綁定;
@ModelAttribute:
請求參數到命令對象的綁定;
@SessionAttributes:
用於聲明session級別存儲的屬性,放置在處理器類上,通常列出
模型屬性(如@ModelAttribute)
對應的名稱,
則這些屬性會透明的保存到session中;
@InitBinder:
自定義數據綁定註冊支持,用於將請求參數轉換到命令對象屬性的對應類型;
三、Spring3.0引入RESTful架構風格支持(通過@PathVariable註解和一些其他特性支持),且又引入了
更多的註解支持:
@CookieValue:
cookie數據到處理器功能處理方法的方法參數上的綁定;
@RequestHeader:
請求頭(header)數據到處理器功能處理方法的方法參數上的綁定;
@RequestBody:
請求的body體的綁定(通過HttpMessageConverter進行類型轉換);
@ResponseBody:
處理器功能處理方法的返回值作爲響應體(通過HttpMessageConverter進行類型轉換);
@ResponseStatus:
定義處理器功能處理方法/異常處理器返回的狀態碼和原因;
@ExceptionHandler:
註解式聲明異常處理器;
@PathVariable:
請求URI中的模板變量部分到處理器功能處理方法的方法參數上的綁定,
從而支持RESTful架構風格的URI;
四、Spring3.1使用新的HandlerMapping 和 HandlerAdapter來支持@Contoller和@RequestMapping
註解處理器。
新的@Contoller和@RequestMapping註解支持類:處理器映射RequestMappingHandlerMapping
和
處理器適配器RequestMappingHandlerAdapter組合來代替Spring2.5開始的處理器映射DefaultAnnotationHandlerMapping和處理器適配器AnnotationMethodHandlerAdapter,
提供更多的擴展點。
接下來,我們一起開始學習基於註解的控制器吧。
②、④、⑥一般是可變的,因此我們可以這些信息進行請求到處理器的功能處理方法的映射,
因此請求的映射分爲如下幾種:
URL路徑映射:使用URL映射請求到處理器的功能處理方法;
請求方法映射限定:如限定功能處理方法只處理GET請求;
請求參數映射限定:如限定只處理包含“abc”請求參數的請求;
請求頭映射限定:如限定只處理“Accept=application/json”的請求。
接下來看看具體如何映射吧。
6.2、入門
(1、控制器實現
- package cn.javass.chapter6.web.controller;
- //省略import
- @Controller // 或 @RequestMapping //①將一個POJO類聲明爲處理器
- public class HelloWorldController {
- @RequestMapping(value = "/hello") //②請求URL到處理器功能處理方法的映射
- public ModelAndView helloWorld() {
- //1、收集參數
- //2、綁定參數到命令對象
- //3、調用業務對象
- //4、選擇下一個頁面
- ModelAndView mv = new ModelAndView();
- //添加模型數據 可以是任意的POJO對象
- mv.addObject("message", "Hello World!");
- //設置邏輯視圖名,視圖解析器會根據該名字解析到具體的視圖頁面
- mv.setViewName("hello");
- return mv; //○3 模型數據和邏輯視圖名
- }
- }
可以通過在一個POJO類上放置@Controller或@RequestMapping,即可把一個POJO類變身爲處理器;
@RequestMapping(value = "/hello")
請求URL(/hello) 到 處理器的功能處理方法的映射;
模型數據和邏輯視圖名的返回。
現在的處理器無需實現/繼承任何接口/類,只需要在相應的類/方法上放置相應的註解說明下即可,
非常方便。
(2、Spring配置文件chapter6-servlet.xml
(2.1、HandlerMapping和HandlerAdapter的配置
如果您使用的是Spring3.1之前版本,開啓註解式處理器支持的配置爲:
DefaultAnnotationHandlerMapping
和AnnotationMethodHandlerAdapter。
如果您使用的Spring3.1開始的版本,建議使用RequestMappingHandlerMapping
和RequestMappingHandlerAdapter。
下一章我們介紹DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter
與RequestMappingHandlerMapping和RequestMappingHandlerAdapter 的區別。
(2.2、視圖解析器的配置
還是使用之前的org.springframework.web.servlet.view.InternalResourceViewResolver。
(2.3、處理器的配置
只需要將處理器實現類註冊到spring配置文件即可,spring的DefaultAnnotationHandlerMapping或RequestMappingHandlerMapping
能根據註解@Controller或@RequestMapping自動發現。
(2.4、視圖頁面(/WEB-INF/jsp/hello.jsp)
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Hello World</title>
- </head>
- <body>
- ${message}
- </body>
- </html>
${message}:表示顯示由HelloWorldController處理器傳過來的模型數據。
(4、啓動服務器測試
地址欄輸入http://localhost:9080/springmvc-chapter6/hello,我們將看到頁面顯示“Hello World!”,
表示成功了。
整個過程和我們第二章中的Hello World 類似,只是處理器的實現不一樣。接下來我們來看一下具體流程吧。
6.3、運行流程
和第二章唯一不同的兩處是:
1、HandlerMapping實現:使用DefaultAnnotationHandlerMapping(spring3.1之前)或RequestMappingHandlerMapping(spring3.1)
替換之前的BeanNameUrlHandlerMapping。
註解式處理器映射會掃描spring容器中的bean,發現bean實現類上擁有
@Controller或@RequestMapping註解的bean,
並將它們作爲處理器。
2、HandlerAdapter實現:使用AnnotationMeth
odHandlerAdapter(spring3.1之前)或RequestMappingHandlerAdapter(spring3.1)替換之前的SimpleControllerHandlerAdapter。
註解式處理器適配器會通過反射調用相應的功能處理方法(方法上擁有@RequestMapping註解
)。
好了到此我們知道Spring如何發現處理器、如何調用處理的功能處理方法了,接下來我們
詳細學習下如何定義處理器、如何進行請求到功能處理方法的定義。
6.4、處理器定義
6.4.1、@Controller
推薦使用這種方式聲明處理器,它和我們的@Service、@Repository很好的對應了我們常見的三層開發架構的組件。
6.4.2、@RequestMapping
這種方式也是可以工作的,但如果在類上使用@ RequestMapping註解一般是用於
窄化功能處理方法的映射的,詳見6.4.3。
- package cn.javass.chapter6.web.controller;
- @Controller
- @RequestMapping(value="/user") //①處理器的通用映射前綴
- public class HelloWorldController2 {
- @RequestMapping(value = "/hello2") //②相對於①處的映射進行窄化
- public ModelAndView helloWorld() {
- //省略實現
- }
- }
6.4.3、窄化請求映射
①類上的@RequestMapping(value="/user") 表示處理器的通用請求前綴;
②處理器功能處理方法上的是對①處映射的窄化。
因此http://localhost:9080/springmvc-chapter6/hello2 無法映射到HelloWorldController2的 helloWorld功能處理方法;而http://localhost:9080/springmvc-chapter6/user/hello2是可以的。
窄化請求映射可以認爲是方法級別的@RequestMapping繼承類級別的@RequestMapping。
窄化請求映射還有其他方式,如在類級別指定URL,而方法級別指定請求方法類型或參數等等,
後續會詳細介紹。
到此,我們知道如何定義處理器了,接下來我們需要學習如何把請求映射到相應的功能處理方法
進行請求處理。
6.5、請求映射
處理器定義好了,那接下來我們應該定義功能處理方法,接收用戶請求處理並選擇視圖進行渲染。
首先我們看一下圖6-1:
http請求信息包含六部分信息:
①請求方法,如GET或POST,表示提交的方式;
②URL,請求的地址信息;
③協議及版本;
④請求頭信息(包括Cookie信息);
⑤回車換行(CRLF);
⑥請求內容區(即請求的內容或數據),如表單提交時的參數數據、URL請求參數(?abc=123 ?後邊的)等。
想要了解HTTP/1.1協議,請訪問http://tools.ietf.org/html/rfc2616。
那此處我們可以看到有①、②、④、⑥一般是可變的,因此我們可以這些信息進行請求到
處理器的功能處理方法的映射,因此請求的映射分爲如下幾種:
URL路徑映射:使用URL映射請求到處理器的功能處理方法;
請求方法映射限定:如限定功能處理方法只處理GET請求;
請求參數映射限定:如限定只處理包含“abc”請求參數的請求;
請求頭映射限定:如限定只處理“Accept=application/json”的請求。
接下來看看具體如何映射吧。