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方法。