註解式控制器運行流程及處理器定義

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、控制器實現


java代碼:
Java代碼  收藏代碼
  1. package cn.javass.chapter6.web.controller;  
  2. //省略import  
  3. @Controller         // 或 @RequestMapping               //①將一個POJO類聲明爲處理器  
  4. public class HelloWorldController {  
  5.     @RequestMapping(value = "/hello")                  //②請求URL到處理器功能處理方法的映射  
  6.     public ModelAndView helloWorld() {  
  7.         //1、收集參數  
  8.         //2、綁定參數到命令對象  
  9.         //3、調用業務對象  
  10.         //4、選擇下一個頁面  
  11.         ModelAndView mv = new ModelAndView();  
  12.         //添加模型數據 可以是任意的POJO對象  
  13.         mv.addObject("message""Hello World!");  
  14.         //設置邏輯視圖名,視圖解析器會根據該名字解析到具體的視圖頁面  
  15.         mv.setViewName("hello");  
  16.         return mv;                                         //○3 模型數據和邏輯視圖名  
  17.     }  
  18. }  


 

可以通過在一個POJO類上放置@Controller或@RequestMapping,即可把一個POJO類變身爲處理器;

@RequestMapping(value = "/hello") 請求URL(/hello) 到 處理器的功能處理方法的映射;

模型數據和邏輯視圖名的返回。

 

現在的處理器無需實現/繼承任何接口/類,只需要在相應的類/方法上放置相應的註解說明下即可,

非常方便。

 

(2、Spring配置文件chapter6-servlet.xml

(2.1、HandlerMapping和HandlerAdapter的配置

如果您使用的是Spring3.1之前版本,開啓註解式處理器支持的配置爲:

DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter。

 

java代碼:
Java代碼  收藏代碼
  1. <!—Spring3.1之前的註解 HandlerMapping -->  
  2. <bean   
  3. class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>  
  4.   
  5. <!—Spring3.1之前的註解 HandlerAdapter -->  
  6. <bean   
  7. class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>  
  8.       

 

如果您使用的Spring3.1開始的版本,建議使用RequestMappingHandlerMapping和RequestMappingHandlerAdapter。

 

java代碼:
Java代碼  收藏代碼
  1. <!--Spring3.1開始的註解 HandlerMapping -->  
  2. <bean   
  3. class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>  
  4. <!--Spring3.1開始的註解 HandlerAdapter -->  
  5. <bean  
  6. class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>  

 

下一章我們介紹DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter

與RequestMappingHandlerMapping和RequestMappingHandlerAdapter 的區別。

 

(2.2、視圖解析器的配置

還是使用之前的org.springframework.web.servlet.view.InternalResourceViewResolver。

(2.3、處理器的配置

 

 

java代碼:
Java代碼  收藏代碼
  1. <!-- 處理器 -->  
  2. <bean class="cn.javass.chapter6.web.controller.HelloWorldController"/>  

 

只需要將處理器實現類註冊到spring配置文件即可,spring的DefaultAnnotationHandlerMapping或RequestMappingHandlerMapping

能根據註解@Controller或@RequestMapping自動發現。

 

(2.4、視圖頁面(/WEB-INF/jsp/hello.jsp)

 

 

java代碼:
Java代碼  收藏代碼
  1. <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>  
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
  3. <html>  
  4. <head>  
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  6. <title>Hello World</title>  
  7. </head>  
  8. <body>  
  9. ${message}  
  10. </body>  
  11. </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實現:使用AnnotationMethodHandlerAdapter(spring3.1之前)或RequestMappingHandlerAdapter(spring3.1)替換之前的SimpleControllerHandlerAdapter

註解式處理器適配器會通過反射調用相應的功能處理方法(方法上擁有@RequestMapping註解)。

 

好了到此我們知道Spring如何發現處理器、如何調用處理的功能處理方法了,接下來我們

詳細學習下如何定義處理器、如何進行請求到功能處理方法的定義。

 

6.4、處理器定義

6.4.1、@Controller

 

java代碼:
Java代碼  收藏代碼
  1. @Controller  
  2. public class HelloWorldController {  
  3. ……  
  4. }  

 

推薦使用這種方式聲明處理器,它和我們的@Service、@Repository很好的對應了我們常見的三層開發架構的組件。

 

6.4.2、@RequestMapping

 

java代碼:
Java代碼  收藏代碼
  1. @RequestMapping  
  2. public class HelloWorldController {  
  3. ……  
  4. }  

 

這種方式也是可以工作的,但如果在類上使用@ RequestMapping註解一般是用於

窄化功能處理方法的映射的,詳見6.4.3。

 

 

Java代碼  收藏代碼
  1. package cn.javass.chapter6.web.controller;  
  2. @Controller  
  3. @RequestMapping(value="/user")                 //①處理器的通用映射前綴  
  4. public class HelloWorldController2 {  
  5.     @RequestMapping(value = "/hello2")        //②相對於①處的映射進行窄化  
  6.     public ModelAndView helloWorld() {  
  7.          //省略實現  
  8.     }  
  9. }  

6.4.3、窄化請求映射

 

java代碼:
Java代碼  收藏代碼
  1. package cn.javass.chapter6.web.controller;  
  2. @Controller  
  3. @RequestMapping(value="/user")                 //①處理器的通用映射前綴  
  4. public class HelloWorldController2 {  
  5.     @RequestMapping(value = "/hello2")        //②相對於①處的映射進行窄化  
  6.     public ModelAndView helloWorld() {  
  7.          //省略實現  
  8.     }  
  9. }  

①類上的@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”的請求。

 

接下來看看具體如何映射吧。

發佈了4 篇原創文章 · 獲贊 0 · 訪問量 9810
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章