基於註解的Spring mvc 簡單瞭解

通過一個實例的方式來寫這篇博客吧,
假設我現在要創建一個 User

public class User {
    private String userName;
    private String userPassword;
    private Keshi keshi;
    /*setter,getter方法*/
    }

Keshi(音譯:科室)也是一個類

public class Keshi {

    private String keshiId;
    private String keshiName;
    }

現在我想創建一個 User ,創建以前 ,讓我們來想想Keshi這個類

Keshi肯定是要從數據庫中取出來的,然後在頁面給用戶選擇,不是User自己填寫的 。

所以可以把顯示填寫的用戶信息的控制器這樣寫

@Controller
public class KeshiController{

    /*@Autowired(required=false)  
    private KeShiManager keshiService;*/

    @RequestMapping(value = {"/keshilist.do"})
    public String list(ModelMap model) {

            List<Keshi> list=new ArrayList<>();

            Keshi keshi1 = new Keshi();
            Keshi keshi2 = new Keshi();
            keshi1.setKeshiId("1");
            keshi1.setKeshiName("測試1");
            keshi2.setKeshiId("2");
            keshi2.setKeshiName("測試2");
            list.add(keshi1);
            list.add(keshi2); 
            model.addAttribute("keshilist",list);
            return "userAdd";
    }
}

當我們不用基於註解的時候,我們需要給我們的Controller直接或者間接實現Controller,並且在xml中配置HandMapping,這樣我們的DispatcherServlet才能找出這個Controller,並讓他”幹活”
說一說這個類:
@Controller
這個註解 是表明這個類可以作爲一個Controller類用,當你在webapplicationContext.xml中配置

 <!-- 配置掃描路徑,base-package包中的@Controller會被全部掃面, -->
        <context:component-scan 
        base-package="com.annotationController,com.wl.assertManagment.web"/>

如上所示,base-package可以配置你要掃描的包,如果有多個包,框架都會掃描,你也可以配置成base-package =“com”這樣com中的所有類和com的子包,都會被掃描.

@RequestMapping(value = {“/keshilist.do”})
@RequeatMapping註解可以用於類上面,也可以用於方法面,表示這個類可以處理“keshilist.do”這個請求。
除此之外,在使用@RequestMapping時,你也可以指定,RequestMethod這個屬性
例如:
@RequestMapping(value=”/b.do”, method={RequestMethod.POST,RequestMethod.GET})
POST表明這個方法只處理POST提交的請求,GET不處理,反過來也是一樣的。當然這些你可以放在類上面聲明,也可以放在方法上聲明(方法聲明上必須放一個@RequestMapping,這樣框架才知道你要調用哪一個方法去處理這個請求)。如果類上加了方法上也加了,那麼就是類上的加上方法上的url
比如:類上的是@RequestMapping(value=”/test”),方法上的是@RequestMapping(value=”/index.do”)那麼這個類的這個方法對應的請求的路徑就是“test/index.do”;

@RequestMapping還有一個params屬性,這個屬性可以讓使用這個屬性的Controller獲得和MultiController同樣的效果,
params要請求指定請求中的參數,例如:

@RequestMapping(method={RequestMethod.GET},params="params=values")

這個標記在某個方法上,表示這個方法處理的請求必須數GET得到的請求,並且請求中必須包含“params=values”這個參數,不僅要求參數的名字是”params”而且要求值必須是“values”,至於這個參數的位置則沒有要求,有無其他參數也沒有要求,只要有這個參數,並且值符合要求,則就框架就能讓這個方法處理。post也一樣,
上面的用法難免有點強人所難的嫌疑,所有框架也允許只使用參數名

@RequestMapping(method={RequestMethod.GET},params="params")

這時候,只要你的請求中包含參數名爲“params”就行,至於其他的值,位置,有無其他的參數都不重要,框架只認”params”。這時候就能在一個類裏面CRUD操作了。(目前我用的最多的就是引導頁面。。)
除此之外還有就是params=”!params”同理這是不要出現參數名爲“params”的請求。

之後就是方法的參數:
原則上你可以使用普通java的方法所有可以使用的參數,不過使用以下的這些方法,可以更方便:
1.request/response/session
2.org.springframework.web.context.request.WebRequest
3.java.io.InputStream/java.io.Reqder
4.java.io.OutputStream/java.io.Writer
5.java.util.Locale
6.java.util.Map/org.sparingframework.ui.ModelMap
以上這些類,只要你在參數中聲明瞭。框架就能保證你能拿到這些東西,

/*原理是,框架在調用你定義的處理方法前會先拿到這些方法,之後根據你的方法聲明,把相應的對象傳遞進去。*/
MaodelAndView mav = ...
ModelMap modelMap = new ModelMap();

/*調用方法*/
processMethod(modelMap)

mav.addAllObject(modelMap)
return mav;

返回類型
1.ModelAndView(典型的返回類型)
2.String(邏輯視圖名字,模型數據根據需要,通過其他途徑獲取)
3.ModelMap(模型數據,採用默認的規則獲取邏輯視圖)

<!-- 配置viewResolver -->
        <bean id="viewResolver"
            class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/" />
            <property name="suffix" value=".jsp" />
        </bean> 
//方法  
        @RequestMapping(value="/test.do",method={RequestMethod.GET,RequestMethod.POST},params="a")
    public void mya1() {
        System.out.println("may1");
    }
    /*以上方法將根據請求名:/test.do  到webContext下去找“test.jsp”*/

4.void(結合String和ModelMap處理)

在返回到我們的例子看一下,定義了一個KeshiController,並模擬產生了keshi的數據,並放到ModelMap中,
這樣在頁面上就能拿到模型數據中的數據了

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title></title>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>

  <body>
   <form action="addUser.do" method="post" name="myform">
      <input type="text" name="userName" /><br/>
      <input type="password" name="userPassword" /><br/>

      <select name="keshi.keshiId" class="form-control" id="sel">

        <c:forEach var="keshi" items="${keshilist}">  
          <option value="${keshi.keshiId}">${keshi.keshiName}</option>
        </c:forEach> 

      </select>

      <!--jsp只能傳遞字符串,不能傳遞對象,所以不能直接將用戶選中keshi類
                傳給後臺,
        隱藏域,傳遞 user.keshi.keshiName-->
      <input type="hidden" name="keshi.keshiName" value="${keshilist[0].keshiName}" id="keshiName"/>   

      <input type="submit" value="提交" />
    </form>    
  </body>

  <script>
  /*通過js來解決用戶選擇後,keshiId與keshiName不一致的問題*/
    var sel=document.getElementById("sel");

    sel.onchange= function(){

            document.getElementById("keshiName").value = 
                sel.options[sel.selectedIndex].text;

            alert(document.getElementById("keshiName").value);
        }
   </script>

</html>

UserController

@Controller
public class UserController {

    @RequestMapping("/addUser.do")
    public String addUser(User user) {  
        return "success";
    }
}

請求參數到方法參數的綁定
如果你的請求包含參數名,與參數包含的參數名一致,框架就能保證相應的參數能對號入座。
例如:

///mya.do?str=asdasdasd&a=1
@RequestMapping(method={RequestMethod.GET,RequestMethod.POST},params="a")
    public void mya1(String a, String str) {
        ...
    //參數的順序不影響,關鍵是名字一定要一樣
    //如果名字不一樣,就有可能出問題,
    /*如果請求中有一個 ..&age=20,而參數中沒有這個名字,或者名字不一樣如:'ages',這時框架不能找到名爲‘ages’的請求參數,所有會給ages賦一個null,而int是無法接受這個事實的,所有會報錯,如果是String或其他應用類型,則就純粹是一個null*/
    }

以上,如果非要用請求參數ages,則可以使用@RequestParam(“name”)

@RequestParam(“name”)
這個註釋可以綁定請求參數到方法參數的對應關係
例如:

@RequestMapping(method={RequestMethod.GET,RequestMethod.POST},params="a")
    public void mya1(@RequestParam("age") int ages, String str) {
        /*這樣請求參數的age,就可以綁定到ages上了*/

    }
    /*如果@RequestParam(“name”)標明的請求參數不存在,程序會拋出異常,@RequestParam的required屬性,默認是‘true’,所有會拋出異常,可以改成‘false’*/

    @RequestMapping(method={RequestMethod.GET,RequestMethod.POST},params="a")
    public void mya1(@RequestParam(value="age",required=false) int ages, String str) {
        /*這樣即使請求參數不包含age,也不會拋出異常*/

    }

指定javaBean對象應用
如上面我們的例子,方法參數可以使用對象,只要給javaBean提供setter方法,並且請求參數名稱與javaBean對應的屬性名稱一樣就,框架就能保證數據綁定正確。
如果你想傳一個對象過去是不行的,因爲,請求參數的傳遞只能是傳字符,jsp會把你的keshi對象換成toString()得到的字符串

這裏寫圖片描述
或者
這裏寫圖片描述
(看你有沒有重寫keshi的toString()方法)
jsp會把字符“com.wl.assertManagment.web.Keshi@1519077”傳遞給UserController進行數據綁定,你試圖將一個String賦值給一個類。肯定不行,所有會拋出異常
這裏寫圖片描述
所有你要麼在傳遞keshiId然後在UserController中調用方法查找出對應的keshi對象,賦值,要麼,想我這樣通過一個隱藏域將name傳遞過去,這裏是keshi的屬性不多,如果屬性很多,推薦在後臺賦值。也可以寫一個自己的“ editors or conversion strategy ”
太麻煩了,(中間有一次手殘,寫好了,沒發表,點了關機,辛辛苦苦寫的全沒了,內心幾乎是崩潰的。)以後還是要分開寫。。。有時間更新

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