1、 用戶發送請求給服務器。url:user
2、 服務器收到請求。發現Dispatchservlet可以處理。於是調用DispatchServlet。
3、 DispatchServlet內部,通過HandleMapping檢查這個url有沒有對應的Controller。如果有,則調用Controller。
4、 Control開始執行
5、 Controller執行完畢後,如果返回字符串,則ViewResolver將字符串轉化成相應的視圖對象;如果返回ModelAndView對象,該對象本身就包含了視圖對象信息。
6、 DispatchServlet將執視圖對象中的數據,輸出給服務器。
7、 服務器將數據輸出給客戶端
相關jar包含義:
1、 org.springframework.aop-3.0.3.RELEASE.jar -----> spring的aop面向切面編程
2、 org.springframework.asm-3.0.3.RELEASE.jar -----> spring獨立的asm字節碼生成程序
3、 org.springframework.beans-3.0.3.RELEASE.jar -----> IOC的基礎實現
4、 org.springframework.context-3.0.3.RELEASE.jar -----> IOC基礎上的擴展服務
5、 org.springframework.core-3.0.3.RELEASE.jar -----> spring的核心包
6、 org.springframework.expression-3.0.3.RELEASE.jar -----> spring的表達式語言
7、 org.springframework.web-3.0.3.RELEASE.jar -----> web工具包
8、 org.springframework.web.servlet-3.0.3.RELEASE.jar -----> mvc工具包
注解
1、@Controller
@Controller
public class UserController {
.......
.......
}
和Struts1一樣,Spring的Controller是Singleton的。這就意味著會被多個請求線程共享。因此,我們將控制器設計成無狀態類。
下為web.xml裡面配置
<!-- Spring MVC配置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</context-param>
需要在spring-mvc.xml配置(包名為你controller所在的包)
<!-- 掃描類包,將標注Spring注解的類自動轉化Bean,同時完成Bean的注入 -->
<context:component-scan base-package="controller" />
① 在類前面定義,則將url和類綁定;(如果該類裡只有單個方法的話可以這樣寫,訪問該地址直接調用該方法)
示例代碼如下:
@Controller
@RequestMapping("/queryuser")
public class UserController {
......
......
}
② 在方法前面定義,則將url和類的方法綁定。
示例代碼如下:
@Controller
public class UserController {
@RequestMapping("/queryuser")
public Object queryUserList(HttpServletRequest request, HttpServletResponse response) {
.....
.....
}
}
3、@RequestParam
A) 常用來處理簡單類型的綁定,通過Request.getParameter() 獲取的String可直接轉換為簡單類型的情況( String--> 簡單類型的轉換操作由ConversionService配置的轉換器來完成);因為使用request.getParameter()方式獲取參數,所以可以處理get 方式中queryString的值,也可以處理post方式中 body data的值;
B)用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容,提交方式GET、POST;
C) 該注解有兩個屬性: value、required; value用來指定要傳入值的id名稱,required用來指示參數是否必須綁定;
/**
* 刪除代理商操作
* **/
@RequestMapping(value = "/del")
@ResponseBody
public MsgBean deleteAgents(@RequestParam("ids")String ids[]){
MsgBean msg = null;
try {
msg = agentsService.delAgents(ids);
} catch (Exception e) {
logger.error("代理商刪除操作出錯..." + e.getMessage());
throw new BusinessException(e.getMessage());
}
return msg;
}
@Controller
public class PersonController {
/**
* 查詢個人信息
*
* @param id
* @return
*/
@RequestMapping(value = "/person/profile/{id}/{name}/{status}", method = RequestMethod.GET)
public @ResponseBody
Person porfile(@PathVariable int id, @PathVariable String name,
@PathVariable boolean status) {
return new Person(id, name, status);
}
/**
* 登錄
*
* @param person
* @return
*/
@RequestMapping(value = "/person/login", method = RequestMethod.POST)
public @ResponseBody
Person login(@RequestBody Person person) {
return person;
}
}
備注:@RequestMapping(value = "/person/profile/{id}/{name}/{status}", method = RequestMethod.GET)中的{id}/{name}/{status}與@PathVariable int id, @PathVariable String name,@PathVariable boolean status一一對應,按名匹配。這是restful式風格。
如果映射名稱有所不一,可以參考如下方式:
@RequestMapping(value = "/person/profile/{id}", method = RequestMethod.GET)
public @ResponseBody
Person porfile(@PathVariable("id") int uid) {
return new Person(uid, name, status);
}
4、@ResponseBody
作用:
該注解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換為指定格式後,寫入到Response對象的body數據區。
使用時機:
返回的數據不是html標簽的頁面,而是其他某種格式的數據時(如json、xml等)使用;
代碼如上
5、@RequestBody
作用:
i) 該注解用於讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然後把相應的數據綁定到要返回的對象上;
ii) 再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。
使用時機:
A) GET、POST方式提時, 根據request header Content-Type的值來判斷:
B) PUT方式提交時, 根據request header Content-Type的值來判斷:
說明:request的body部分的數據編碼格式由header部分的Content-Type指定;
6、@SessionAttributes
@SessionAttributes:
該注解用來綁定HttpSession中的attribute對象的值,便於在方法中的參數裡使用。
該注解有value、types兩個屬性,可以通過名字和類型指定要使用的attribute 對象;
@Controller
@RequestMapping("/user")
@SessionAttributes({"u","a"}) //將ModelMap中屬性名字為u、a的再放入session中。這樣,request和session中都有了。
publicclass UserController {
@RequestMapping(params="method=list")
public String list(ModelMap map) {
System.out.println("HelloController.handleRequest()");
map.addAttribute("u","users"); //將u放入request作用域中,這樣轉發頁面也可以取到這個數據。
return"index";
}
}
index裡面的代碼
<body>
<h1>${requestScope.u.uname}</h1>
<h1>${sessionScope.u.uname}</h1>
</body>
7、@ModelAttribute
該注解有兩個用法,一個是用於方法上,一個是用於參數上;
用於方法上時: 通常用來在處理@RequestMapping之前,為請求綁定需要從後台查詢的model;
用於參數上時: 用來通過名稱對應,把相應名稱的值綁定到注解的參數bean上;要綁定的值來源於:
A) @SessionAttributes 啟用的attribute 對象上;
B) @ModelAttribute 用於方法上時指定的model對象;
C) 上述兩種情況都沒有時,new一個需要綁定的bean對象,然後把request中按名稱對應的方式把值綁定到bean中。
用到方法上@ModelAttribute的示例代碼:
@ModelAttribute
public Account addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
}
這種方式實際的效果就是在調用@RequestMapping的方法之前,為request對象的model裡put(“account”, Account);
用在參數上的@ModelAttribute示例代碼:
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) {
}
首先查詢 @SessionAttributes有無綁定的Pet對象,若沒有則查詢@ModelAttribute方法層面上是否綁定了Pet對象,若沒有則將URI template中的值按對應的名稱綁定到Pet對象的各屬性上。
@ModelAttribute可以和@SessionAttributes配合在一塊使用。可以通過ModelMap中屬性的值通過該注解自動賦給指定變量。
示例代碼如下:
@Controller
@RequestMapping("/user")
@SessionAttributes({"u","a"})
publicclass UserController {
@RequestMapping(params="method=list1")
public String list1(ModelMap map) {
System.out.println("HelloController.handleRequest()");
map.addAttribute("u","光頭強");
return"index";
}
@RequestMapping(params="method=list2")
public String list2(@ModelAttribute("u")String username ,ModelMap map) {
System.out.println("HelloController.handleRequest()");
System.out.println(username );
return"index";
}
}
上述先調用list1方法,再調用list2方法。