Spring mvc

轉自 http://blog.csdn.net/ning109314/article/details/7595403


在傳統的Spring MVC開發方法中,必須在Bean配置文件中爲每個控制器類配置實例和請求映射和讓每個控制器類去實現或者擴展特定於框架的接口或者基類,不夠靈活。

如果Spring MVC可以自動偵測你的控制器類和請求映射,就能減少配置所需要的工作量。

Spring2.5支持一種基於註解的控制器開發方法。

Spring可以通過@Controller註解自動發現你的控制器類以及@RequestMapping註解中的請求映射,這樣就爲你免去了在Bean配置文件中配置它們的麻煩。此外,如果使用註解,控制器類和處理程序方法在訪問上下文資源(例如請求參數、模型屬性和會話屬性)時也會更加靈活。

常用到的註解

 

1、@Controller
 
2、@RequestMapping
 
3、@RequestParam,  @PathVariable,  @CookieValue
 
@Controller註解能將任意的類標註成控制器類。與傳統的控制器相反,被標註的控制器類不需要實現特定於框架的接口,也不必擴展特定於框架的基類
在控制器類內部,可能有一個或者多個處理程序方法添加了@RequestMapping註解。
 

 

處理程序方法的簽名非常靈活。你可以爲處理程序方法指定任意的名稱,並定義以下任意一種類型作爲它的方法參數。在這裏,只提到了常見的參數類型。關於有效參數類型的完整列表,請參閱有關配置基於註解的控制器的Spring文檔。

 

見的參數類

 

1.HttpServletRequest、HttpServletResponse或HttpSession。

2.添加了@RequestParam註解的任意類型的請求參數

3.添加了@ModelAttribute註解的任意類型的模型屬性

4.任意類型的命令對象,供Spring綁定請求參數

5.Map或者ModelMap,供處理程序方法向模型添加屬性

6.Errors或者BindingResult,讓處理程序方法訪問命令對象的綁定和驗證結果

7.SessionStatus,讓處理程序方法發出會話處理已經完成的通知

 

 

常見的返回值類型

 

處理程序方法的返回類型可以是ModelAndView、Model、Map、String、void

 

 

在創建基於註解的控制器之前,必須構建web應用程序上下文來處理註解。

首先,爲了讓Spring用@Controller註解自動偵測控制器,必須通過<context:component-scan>元素啓用Spring的組件掃描特性。

其次Spring MVC還能夠根據@RequestMapping將請求映射到控制器類和處理程序方法。

爲了使其生效,必須在web應用程序上下文中註冊DefaultAnnotationHandlerMapping實例和AnnotationMethodHandlerAdapter實例。

它們分別處理在類級別方法級別上的@RequestMapping註解

 

 

必要的Spring MVC配置

Xml代碼
[xml] view plain copy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.         xmlns:mvc="http://www.springframework.org/schema/mvc"  
  5.         xmlns:context="http://www.springframework.org/schema/context"  
  6.         xsi:schemaLocation="  
  7.           http://www.springframework.org/schema/beans  
  8.           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  9.           http://www.springframework.org/schema/mvc/spring-mvc  
  10.           http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
  11.           http://www.springframework.org/schema/context  
  12.           http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
  13.   
  14.     <!-- 自動掃描註解的Controller -->  
  15.     <context:component-scan base-package="com.wy.controller.annotation" />  
  16.       
  17.     <!-- 處理在類級別上的@RequestMapping註解-->  
  18.     <bean  
  19.         class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />  
  20.     <!-- 處理方法級別上的@RequestMapping註解-->  
  21.     <bean  
  22.         class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />  
  23.        
  24.        
  25.     <!-- 視圖解析器策略 和 視圖解析器 -->  
  26.     <!-- 對JSTL提供良好的支持 -->  
  27.     <bean  
  28.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
  29.         <!-- 默認的viewClass,可以不用配置  
  30.         <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView" />  
  31.          -->  
  32.         <property name="prefix" value="/WEB-INF/page/" />  
  33.         <property name="suffix" value=".jsp" />  
  34.     </bean>  
  35.           
  36. </beans>  

 DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter是默認在Web應用程序上下文中預先註冊好的。然而,如果你還顯式地註冊了其他的處理程序映射或者處理程序適配器,它們就不會自動註冊了。在這種情況下,你必須親自注冊它們。

 

基於註解的控制器類可以是個任意類,不實現特殊接口,也不擴展特殊的基類。你只要用@Controller註解對它進行標註即可。還可以在控制器中定義一個或者多個處理程序方法來處理單個或者多個動作。處理程序方法的簽名很靈活,足以接受一系列參數。

 

 @RequestMapping註解可以被應用到類級別或者方法級別上

 

Controller層:代碼中寫了很詳細的註釋

Java代碼
[java] view plain copy
  1. package com.wy.controller.annotation;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.PrintWriter;  
  5. import java.text.SimpleDateFormat;  
  6. import java.util.Date;  
  7. import java.util.HashMap;  
  8. import java.util.List;  
  9. import java.util.Map;  
  10.   
  11. import javax.servlet.http.HttpServletRequest;  
  12. import javax.servlet.http.HttpServletResponse;  
  13.   
  14. import org.springframework.beans.propertyeditors.CustomDateEditor;  
  15. import org.springframework.stereotype.Controller;  
  16. import org.springframework.ui.Model;  
  17. import org.springframework.validation.BindingResult;  
  18. import org.springframework.validation.FieldError;  
  19. import org.springframework.web.bind.ServletRequestDataBinder;  
  20. import org.springframework.web.bind.annotation.InitBinder;  
  21. import org.springframework.web.bind.annotation.PathVariable;  
  22. import org.springframework.web.bind.annotation.RequestMapping;  
  23. import org.springframework.web.bind.annotation.RequestMethod;  
  24. import org.springframework.web.bind.annotation.RequestParam;  
  25. import org.springframework.web.bind.support.WebRequestDataBinder;  
  26. import org.springframework.web.servlet.ModelAndView;  
  27.   
  28. import com.wy.pojo.User;  
  29.   
  30. /** 
  31.  * @author Administrator 
  32.  * @version 2011-12-3 
  33.  */  
  34.   
  35. @Controller  
  36. @RequestMapping("userManagerContoller"//指定請求路徑,相對路徑可以不定義  
  37. public class UserManagerContoller {  
  38.   
  39.     /** 
  40.      * 歡迎 
  41.      * @return 
  42.      */  
  43.       
  44.     /* 1.傳統的獲取請求的參數方式 
  45.      * http://localhost:8080/SpringMVC/userManagerContoller/welcome.do?name=wy 
  46.      */  
  47.     @RequestMapping("/welcome")   
  48.     public ModelAndView welcome(HttpServletRequest request){    
  49.         ModelAndView mav = new ModelAndView();  
  50.         String name = request.getParameter("name");  
  51.         Date today = new Date();    
  52.         String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(today);  
  53.         mav.addObject("today", date);  
  54.         mav.addObject("name", name);  
  55.         mav.setViewName("welcome");  
  56.         return mav;    
  57.     }  
  58.       
  59.     /* 2.restful風格獲取請求的參數方式  Spring3.0的一個重要變化(將參數放到了請求路徑中) 
  60.      * http://localhost:8080/SpringMVC/userManagerContoller/welcome/wy.do 
  61.      *  
  62.      * 注意點: JVM將Java文件編譯成Class文件有兩種模式 Debug 和Release 
  63.      * 這兩種編譯方式的區別是: 
  64.      *    Debug 包含額外的調試信息,可以完整的保留變量的名稱 (Eclipse 使用的是Debug) 
  65.      *    Release 把變量名稱使用其他的一些符號代替,量名稱就不可見啦 (在使用 javac命令)    
  66.      */  
  67.     @RequestMapping("/welcome/{param}/{sex}")  
  68.     //前一個“param是防止Release編譯下找不到參數名稱,因此要指定;要和模板中定義的參數名稱一致  
  69.     //後面一個“param”可以和模板中定義的參數名稱不一致,建議還是一致  
  70.     public ModelAndView welcome(@PathVariable("param") String param, @PathVariable("sex") String xingbie){  
  71.         ModelAndView mav = new ModelAndView();  
  72.         mav.addObject("name", param);  
  73.         mav.addObject("sex", xingbie);  
  74.         Date today = new Date();    
  75.         String date = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(today);  
  76.         mav.addObject("today", date);  
  77.         mav.setViewName("welcome");  
  78.         return mav;  
  79.     }  
  80.       
  81.     /** 
  82.      * 3.不同請求方式(get,post),映射不同的方法 
  83.      *  
  84.      *   value 指定請求路徑,method 指定請求方式 
  85.      */  
  86.     @RequestMapping(value="/welcome", method=RequestMethod.GET)  
  87.     public ModelAndView requestMethodGet(){  
  88.         ModelAndView mav = new ModelAndView();  
  89.         mav.setViewName("welcome");  
  90.         return mav;  
  91.     }  
  92.   
  93.     @RequestMapping(value="/hello", method=RequestMethod.POST)  
  94.     public ModelAndView requestMethodPost(){  
  95.         ModelAndView mav = new ModelAndView();  
  96.         mav.setViewName("hello");  
  97.         return mav;  
  98.     }  
  99.       
  100.     /** 
  101.      * 4. @RequestParam 使用方法和@PathVariable類似(要注意Debug和Release) 
  102.      *    http://localhost:8080/SpringMVC/userManagerContoller/welcomeParam.do?username=wy&password=123&age=23 
  103.      */  
  104.     @RequestMapping(value="/welcomeParam", method=RequestMethod.GET)  
  105.     public ModelAndView welcome(@RequestParam("username") String username,  
  106.             @RequestParam("password") String password, @RequestParam("age"int age) {  
  107.         ModelAndView mav = new ModelAndView();  
  108.         User user = new User();  
  109.         user.setUsername(username);  
  110.         user.setPassword(password);  
  111.         user.setAge(age);  
  112.         mav.addObject("user", user);  
  113.         mav.setViewName("hello");  
  114.         return mav;  
  115.     }  
  116.       
  117.     /** 
  118.      * 5.獲取表單中的值 
  119.      *   BindingResult 綁定數據過程中產生的錯誤注入到BindingResult中。 
  120.      */  
  121.     @RequestMapping(value="/welcome", method=RequestMethod.POST)  
  122.     public ModelAndView commonCommod(User user, BindingResult result){  
  123.         ModelAndView mav = new ModelAndView();  
  124.         mav.addObject(user);  
  125.         if(result.hasErrors() && result.hasFieldErrors()){  
  126.             String field = null;  
  127.             Object fieldValue = null;  
  128.             Map<String, Object> map = new HashMap<String, Object>();  
  129.             List<FieldError> fieldErrors = result.getFieldErrors();  
  130.             for(FieldError fieldError : fieldErrors){  
  131.                 field = fieldError.getField();  
  132.                 fieldValue = fieldError.getRejectedValue();  
  133.                   
  134.                 map.put(field, fieldValue);  
  135.             }  
  136.             mav.addObject("map", map);  
  137.             mav.setViewName("welcome");  
  138.         }else{  
  139.             mav.setViewName("hello");  
  140.         }  
  141.         return mav;  
  142.     }  
  143.       
  144.     /** 
  145.      * 屬性編輯器 類型轉換 
  146.      * 典型應用: 日期轉換 
  147.      */  
  148.     @InitBinder  
  149.     public void initBinder(WebRequestDataBinder binder){  
  150.         binder.registerCustomEditor(Date.classnew CustomDateEditor(  
  151.                 new SimpleDateFormat("yyyy-MM-dd"),false));  
  152.     }  
  153.       
  154.     public void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception{  
  155.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");  
  156.         dateFormat.setLenient(false);  
  157.         binder.registerCustomEditor(Date.classnew CustomDateEditor(dateFormat, true));  
  158.     }  
  159.     /** 
  160.      * 6.常用的參數 
  161.      *   使用Session有一個前提就是session必須是可用的 
  162.      */  
  163. //  public ModelAndView commonArguments(HttpServletRequest request, HttpServletResponse response, HttpSession session,   
  164. //          @CookieValue AnyType cookieName, @RequestHeader("user-Agent") AnyType name,   
  165. //          @PathVariable AnyType variableName, @RequestParam AnyType paramName){  
  166. //      ModelAndView mav = new ModelAndView();  
  167. //        
  168. //      return mav;  
  169. //  }  
  170.       
  171.     /** 
  172.      * 7.返回類型 
  173.      *   void 、String、AnyType(任意對象)、Model、ModelAndView 
  174.      *   說明:Model繼承了Map,爲SpringMVC定製的 
  175.      */  
  176.     // void  
  177.     @RequestMapping  
  178.     public void commonReturnType(HttpServletResponse response){  
  179.         try {  
  180.             PrintWriter out = response.getWriter();  
  181.             out.println("向頁面中輸出的值");  
  182.         } catch (IOException e) {  
  183.             // TODO Auto-generated catch block  
  184.             e.printStackTrace();  
  185.         }  
  186.     }  
  187.       
  188.     @RequestMapping  
  189.     public void commonReturnType(PrintWriter out){//其實也是從HttpServletResponse 通過getWriter()得到out  
  190.         out.println("向頁面中輸出的值");  
  191.     }  
  192.       
  193.     @RequestMapping("/commonReturnType")  
  194.     public void commonReturnType(){  
  195.         //默認生成隱含的viewName(規則測略:按照請求路徑${appName/userManagerContoller/commonReturnType.do   
  196.         //                                   ---> userManagerContoller/commonReturnType}  
  197.         //                                   ---> /WEB-INF/page/userManagerContoller/commonReturnType.jsp  
  198.         //                  )  
  199.     }  
  200.       
  201.     // String  
  202.     /** 
  203.      * ModelAndView中的Model 
  204.      * ModelAndView中的View 
  205.      */  
  206.     @RequestMapping  
  207.     public String commonReturnType(Map<Object, Object> model){//model  
  208.         model.put("""");  
  209.         return "viewName";  
  210.     }  
  211.       
  212.     //AnyType(任意對象)  
  213.     /** 
  214.      * user放到model中,model(key, value) key默認是取Bean的名稱將其首字母小寫 即user,value即user 
  215.      * 默認生成隱含的viewName 
  216.      * 在頁面上可以使用request.getAttribute("user")或者${user.key} ${user.value} 
  217.      * @return 
  218.      */  
  219.     @RequestMapping  
  220.     public User commonReturnTypeUser(){//  
  221.         User user = null;  
  222.           
  223.         return user;  
  224.     }  
  225.       
  226.     /** 
  227.      * userList放到model中,model(key, value) key默認是框架生成userList,value即user 
  228.      * 默認生成隱含的viewName 
  229.      * 在頁面上可以使用request.getAttribute("userList")或者${userList.key} ${userList.value} 
  230.      * @return 
  231.      */  
  232.     @RequestMapping  
  233.     public List<User> commonReturnTypeUserList(){  
  234.         List<User> userList = null;  
  235.           
  236.         return userList;  
  237.     }  
  238.       
  239.     /** 
  240.      *  
  241.      * 默認生成隱含的viewName 
  242.      * @return 
  243.      */  
  244.     @RequestMapping  
  245.     public Model commonReturnTypeModel(){  
  246.         Model model = null;  
  247.           
  248.         return model;  
  249.     }  
  250.       
  251.     /** 
  252.      *  
  253.      * @return 
  254.      */  
  255.     @RequestMapping  
  256.     public ModelAndView commonReturnTypeModelAndView(){  
  257.         ModelAndView mav = new ModelAndView();  
  258.           
  259.         mav.addObject("""");  
  260.         mav.setViewName("");  
  261.         return mav;  
  262.     }  
  263.       
  264. }  

 

view層

  welcome.jsp

  

Html代碼
[html] view plain copy
  1. <%@ page language="java" pageEncoding="UTF-8"%>  
  2. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
  3. <%  
  4. String path = request.getContextPath();  
  5. %>  
  6. <!DOCTYPE html>  
  7. <html>  
  8.   <head>  
  9.     <title>welcome.html</title>  
  10.       
  11.     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  12.     <meta http-equiv="description" content="this is my page">  
  13.     <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
  14.       
  15.     <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->  
  16.   
  17.   </head>  
  18.     
  19.   <body>  
  20.     This is my annotation HTML page. <br/>  
  21.           今天是: ${today}<br/>  
  22.           參數是: ${name}&nbsp;&nbsp;&nbsp;${sex}<br/>  
  23.     <hr/>       
  24.     <c:forEach var="field" items="${map}">  
  25.        <c:if test="${field != null}" var="param" scope="page">  
  26.                           您輸入的${field.key}不正確! ${field.value}<br/>  
  27.     </c:if>  
  28.     </c:forEach>  
  29.       
  30.     <form action="<%=path%>/userManagerContoller/welcome.do" method="post">  
  31.                    用戶名: <input type="text" id="username" name="username"  value="wy" /><br/>  
  32.                    密碼 : <input type="text" id="password" name="password"  value="wy" /><br/>  
  33.                    年齡 : <input type="text" id="age"      name="age"       value="23wy" /><br/>            
  34.        <input type="submit" value="提交" />  
  35.     </form>            
  36.   </body>  
  37. </html>  

 

 

值得注意的點:

    1、@PathVariable("paramName") @RequestParam("paramName") 建議指定參數名稱

         原因是VM將Java文件編譯成Class文件有兩種模式 Debug 和Release

         這兩種編譯方式的區別是:

               Debug 包含額外的調試信息,可以完整的保留變量的名稱 (Eclipse 使用的是Debug)

                Release 把變量名稱使用其他的一些符號代替,量名稱就不可見啦 (在使用 javac命令)

       2、restful風格獲取請求的參數方式

       3、參數類型轉換

             註冊屬性編輯器

      4、對於無任何輸出的方法

       

Java代碼
[java] view plain copy
  1. @RequestMapping("/commonReturnType")  
  2.     public void commonReturnType(){  
  3.         //默認生成隱含的viewName(規則測略:按照請求路徑${appName/userManagerContoller/commonReturnType.do   
  4.         //                                   ---> userManagerContoller/commonReturnType}  
  5.         //                                   ---> /WEB-INF/page/userManagerContoller/commonReturnType.jsp  
  6.         //                  )  
  7.     }  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章