# 注解式控制器運行流程及處理器定義 第六章 注解式控制器詳解——跟著開濤學SpringMVC
聲明:本系列都是原創內容,覺得好就頂一個,讓更多人知道!!?希望那些踩的人給出不好的理由,我會積極改正。寫博客不容易,寫原創更不容易!!
##
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之前的注解 HandlerMapping -->
<bean
class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<!—Spring3.1之前的注解 HandlerAdapter -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
```
`如果您使用的Spring3.1開始的版本,建議使用RequestMappingHandlerMapping`和RequestMappingHandlerAdapter。
```
<!--Spring3.1開始的注解 HandlerMapping -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--Spring3.1開始的注解 HandlerAdapter -->
<bean
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
```
`下一章我們介紹DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter`
`與RequestMappingHandlerMapping和RequestMappingHandlerAdapter 的區別。`
**(2.2、視圖解析器的配置**
`還是使用之前的org.springframework.web.servlet.view.InternalResourceViewResolver。`
**(2.3、處理器的配置**
```
<!-- 處理器 -->
<bean class="cn.javass.chapter6.web.controller.HelloWorldController"/>
```
`只需要將處理器實現類注冊到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](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
```
@Controller
public class HelloWorldController {
……
}
```
推薦使用這種方式聲明處理器,它和我們的@Service、@Repository很好的對應了我們常見的三層開發架構的組件。
### 6.4.2、@RequestMapping
```
@RequestMapping
public class HelloWorldController {
……
}
```
這種方式也是可以工作的,但如果在類上使用@ 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、窄化請求映射
```
package cn.javass.chapter6.web.controller;
@Controller
@RequestMapping(value="/user") //①處理器的通用映射前綴
public class HelloWorldController2 {
@RequestMapping(value = "/hello2") //②相對于①處的映射進行窄化
public ModelAndView helloWorld() {
//省略實現
}
}
```
①類上的@RequestMapping(value="/user") 表示處理器的通用請求前綴;
②處理器功能處理方法上的是對①處映射的窄化。
因此[http://localhost:9080/springmvc-chapter6/hello2 無法映射到HelloWorldController2](http://localhost:9080/springmvc-chapter6/hello2%20%E6%97%A0%E6%B3%95%E6%98%A0%E5%B0%84%E5%88%B0HelloWorldController2)的 helloWorld功能處理方法;而[http://localhost:9080/springmvc-chapter6/user/hello2](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](http://tools.ietf.org/html/rfc2616)。
```
```
那此處我們可以看到有①、②、④、⑥一般是可變的,因此我們可以這些信息進行請求到
```
```
處理器的功能處理方法的映射,因此請求的映射分為如下幾種:
```
URL路徑映射:使用URL映射請求到處理器的功能處理方法;
請求方法映射限定:如限定功能處理方法只處理GET請求;
請求參數映射限定:如限定只處理包含“abc”請求參數的請求;
請求頭映射限定:如限定只處理“Accept=application/json”的請求。
接下來看看具體如何映射吧。
[
私塾在線學習網](http://sishuok.com/)原創內容([http://sishuok.com](http://sishuok.com/))
原創內容,轉載請注明私塾在線【[http://sishuok.com/forum/blogPost/list/0/6117.html](http://sishuok.com/forum/blogPost/list/0/6117.html)[](http://sishuok.com/forum/blogPost/list/5934.html#19650)】
- 跟我學 Spring3
- 【第二章】 IoC 之 2.1 IoC基礎 ——跟我學Spring3
- 【第二章】 IoC 之 2.2 IoC 容器基本原理 ——跟我學Spring3
- 【第二章】 IoC 之 2.3 IoC的配置使用——跟我學Spring3
- 【第三章】 DI 之 3.1 DI的配置使用 ——跟我學spring3
- 【第三章】 DI 之 3.2 循環依賴 ——跟我學spring3
- 【第三章】 DI 之 3.3 更多DI的知識 ——跟我學spring3
- 【第三章】 DI 之 3.4 Bean的作用域 ——跟我學spring3
- 【第四章】 資源 之 4.1 基礎知識 ——跟我學spring3
- 【第四章】 資源 之 4.2 內置Resource實現 ——跟我學spring3
- 【第四章】 資源 之 4.3 訪問Resource ——跟我學spring3
- 【第四章】 資源 之 4.4 Resource通配符路徑 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.1 概述 5.2 SpEL基礎 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.3 SpEL語法 ——跟我學spring3
- 【第五章】Spring表達式語言 之 5.4在Bean定義中使用EL—跟我學spring3
- 【第六章】 AOP 之 6.1 AOP基礎 ——跟我學spring3
- 【第六章】 AOP 之 6.2 AOP的HelloWorld ——跟我學spring3
- 【第六章】 AOP 之 6.3 基于Schema的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.4 基于@AspectJ的AOP ——跟我學spring3
- 【第六章】 AOP 之 6.5 AspectJ切入點語法詳解 ——跟我學spring3
- 【第六章】 AOP 之 6.6 通知參數 ——跟我學spring3
- 【第六章】 AOP 之 6.7 通知順序 ——跟我學spring3
- 【第六章】 AOP 之 6.8 切面實例化模型 ——跟我學spring3
- 【第六章】 AOP 之 6.9 代理機制 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.1 概述 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.2 JDBC模板類 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.3 關系數據庫操作對象化 ——跟我學spring3
- 【第七章】 對JDBC的支持 之 7.4 Spring提供的其它幫助 ——跟我學spring3【私塾在線原創】
- 【第七章】 對JDBC的支持 之 7.5 集成Spring JDBC及最佳實踐 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.1 概述 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.2 集成Hibernate3 ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.3 集成iBATIS ——跟我學spring3
- 【第八章】 對ORM的支持 之 8.4 集成JPA ——跟我學spring3
- 【第九章】 Spring的事務 之 9.1 數據庫事務概述 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.2 事務管理器 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.3 編程式事務 ——跟我學spring3
- 【第九章】 Spring的事務 之 9.4 聲明式事務 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.1 概述 ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.2 集成Struts1.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.3 集成Struts2.x ——跟我學spring3
- 【第十章】集成其它Web框架 之 10.4 集成JSF ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.1 概述 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.2 實現通用層 ——跟我學spring3
- 【第十一章】 SSH集成開發積分商城 之 11.3 實現積分商城層 ——跟我學spring3
- 【第十二章】零配置 之 12.1 概述 ——跟我學spring3
- 【第十二章】零配置 之 12.2 注解實現Bean依賴注入 ——跟我學spring3
- 【第十二章】零配置 之 12.3 注解實現Bean定義 ——跟我學spring3
- 【第十二章】零配置 之 12.4 基于Java類定義Bean配置元數據 ——跟我學spring3
- 【第十二章】零配置 之 12.5 綜合示例-積分商城 ——跟我學spring3
- 【第十三章】 測試 之 13.1 概述 13.2 單元測試 ——跟我學spring3
- 【第十三章】 測試 之 13.3 集成測試 ——跟我學spring3
- 跟我學 Spring MVC
- SpringMVC + spring3.1.1 + hibernate4.1.0 集成及常見問題總結
- Spring Web MVC中的頁面緩存支持 ——跟我學SpringMVC系列
- Spring3 Web MVC下的數據類型轉換(第一篇)——《跟我學Spring3 Web MVC》搶先看
- Spring3 Web MVC下的數據格式化(第二篇)——《跟我學Spring3 Web MVC》搶先看
- 第一章 Web MVC簡介 —— 跟開濤學SpringMVC
- 第二章 Spring MVC入門 —— 跟開濤學SpringMVC
- 第三章 DispatcherServlet詳解 ——跟開濤學SpringMVC
- 第四章 Controller接口控制器詳解(1)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(2)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(3)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解 (4)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(5)——跟著開濤學SpringMVC
- 跟著開濤學SpringMVC 第一章源代碼下載
- 第二章 Spring MVC入門 源代碼下載
- 第四章 Controller接口控制器詳解 源代碼下載
- 第四章 Controller接口控制器詳解(6)——跟著開濤學SpringMVC
- 第四章 Controller接口控制器詳解(7 完)——跟著開濤學SpringMVC
- 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 源代碼下載 第五章 處理器攔截器詳解——跟著開濤學SpringMVC
- 注解式控制器運行流程及處理器定義 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- 源代碼下載 第六章 注解式控制器詳解
- SpringMVC3強大的請求映射規則詳解 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- Spring MVC 3.1新特性 生產者、消費者請求限定 —— 第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(1)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC強大的數據綁定(2)——第六章 注解式控制器詳解——跟著開濤學SpringMVC
- SpringMVC數據類型轉換——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據格式化——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC
- SpringMVC數據驗證——第七章 注解式控制器的數據驗證、類型轉換及格式化——跟著開濤學SpringMVC