我的建議從新練習一遍搭建的過程,若是感受麻煩你能夠直接複製上一個工程,可是須要修改pom.xml中的一點信息html
<groupId>com.hanpang.springmvc</groupId>
<artifactId>springmvc-demo02</artifactId>
<version>0.0.1-SNAPSHOT</version>
複製代碼
咱們可使用@RequestMapping標註來將請求URL(相似於@WebServlet),如/hanpang等,映射到整個類上或某個特定的處理器方法上。java
通常來講,類級別的標註負責將一個特定(或符合某種模式)的請求路徑映射到一個控制器上,同時經過方法級別的標註來細化映射,即根據特定的HTTP請求方法(「GET」和「POST」方法等)、HTTP請求中是否攜帶特定參數等條件,將請求映射到匹配的方法上。web
package com.hanpang.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller//告知其是一個控制器
@RequestMapping("/sys")
public class Demo01Controller {
//映射默認的路徑
public ModelAndView test01() {
System.out.println("該方法是訪問sys執行");
return null;
}
//----------------細化--------------------//
//映射一個路徑
@RequestMapping(value="/user01")
public ModelAndView test02() {
System.out.println("/user01 path和value屬性同樣");
return null;
}
//映射一個路徑
@RequestMapping(path="/user02")
public ModelAndView test03() {
System.out.println("/user02 path和value屬性同樣");
return null;
}
//簡寫方式
@RequestMapping("/user03")
public ModelAndView test04() {
System.out.println("/user03 當只有path或者value屬性的時候,可使用簡寫方式");
return null;
}
//多個映射路徑執行一個方法
@RequestMapping(value= {"/user04","/user05"})
public ModelAndView test05() {
System.out.println("設置多個映射路徑");
return null;
}
//簡寫方式
@RequestMapping({"/user06","/user07"})
public ModelAndView test06() {
System.out.println("設置多個映射路徑");
return null;
}
}
複製代碼
閱讀一下,咱們簡單瞭解一下規則就行,主要介紹一下通配符"*"的演示,實際開發中我的基本上沒有使用過.正則表達式
package com.hanpang.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller//告知其是一個控制器
@RequestMapping("/web")
public class Demo02Controller {
@RequestMapping("/*")
public ModelAndView test01() {
System.out.println("* 表明一層");
return null;
}
@RequestMapping("/**")
public ModelAndView test02() {
System.out.println("** 表明任意層次");
return null;
}
}
複製代碼
NOTE: 誰描述的更加準確,就執行誰spring
測試路徑以下:api
http://127.0.0.1:8001/mvc/web/user01 執行tes01方法
http://127.0.0.1:8001/mvc/web/user02 執行tes01方法
http://127.0.0.1:8001/mvc/web/user01/user02 執行tes02方法
http://127.0.0.1:8001/mvc/web/a/b/c/d 執行tes02方法
複製代碼
package com.hanpang.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller//告知其是一個控制器
@RequestMapping("/web")
public class Demo02Controller {
@RequestMapping("/*")
public ModelAndView test01() {
System.out.println("* 表明一層");
return null;
}
@RequestMapping("/role*")
public ModelAndView test02() {
System.out.println("role* 的描述更準確");
return null;
}
@RequestMapping("/role")
public ModelAndView test03() {
System.out.println("role 我更準確");
return null;
}
}
複製代碼
修改以前上面的代碼,咱們繼續測試路徑瀏覽器
http://127.0.0.1:8001/mvc/web/user01 執行test01方法
http://127.0.0.1:8001/mvc/web/roleuser01 執行test02方法
http://127.0.0.1:8001/mvc/web/role 執行test03方法
複製代碼
使用通配符的方式真的不多,可是實際開發中咱們常常使用URI模式,路徑傳遞數據的方式(佔位符),咱們再次修改原來代碼mvc
package com.hanpang.web;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller//告知其是一個控制器
@RequestMapping("/web")
public class Demo02Controller {
@RequestMapping("/*")
public ModelAndView test01() {
System.out.println("* 表明一層");
return null;
}
@RequestMapping("/**")
public ModelAndView test02() {
System.out.println("** 表明一層");
return null;
}
@RequestMapping("/{a}")
public ModelAndView test03() {
System.out.println("{a} 一個佔位符");
return null;
}
@RequestMapping("/{a}/{b}")
public ModelAndView test04() {
System.out.println("/{a}/{b} 多個佔位符");
return null;
}
}
複製代碼
測試路徑:app
http://127.0.0.1:8001/mvc/web/user01 執行test03方法
http://127.0.0.1:8001/mvc/web/user01/user02 執行test04方法
http://127.0.0.1:8001/mvc/web/user01/user02//user03 執行test02方法
複製代碼
NOTE: 發現佔位符的描述性比通配符的描述更加準確框架
當一個URL同時匹配多個模式時,只會選擇最匹配的一個:
/hotels/{hotel}/*
這個路徑擁有一個URI變量和一個通配符,而/hotels/{hotel}/**
這個路徑則擁有一個URI變量和兩個通配符,所以前者是更準確的路徑模式。/foo/bar*
就被認爲比/foo/*
更準確,由於前者的路徑更長。/hotels/{hotel}
就比/hotels/*
更精確。/**
比其餘全部的模式都更"不許確"。比方說,/api/{a}/{b}/{c}
就比默認的通配模式/**
要更準確/public/**
)被認爲比其餘任何不包括雙通配符的模式更不許確。例如,/public/path3/{a}/{b}/{c}
就比/public/**
更準確請重視這種模式,URI模式爲獲取**@RequestMapping**中指定的URL的眸一個特定部分提供很大的方便。
URI模式是一個相似於URI的字符串,只不過其中包含了一個或多個的變量名。當使用實際的值去填充這些變量名的時候,模式就成爲一個URI。好比說,一個這個URI模式http://127.0.0.1/mvc/shxt/{userId}
就包含了一個變量名userId。將值1001賦給這個變量名後,它就變成了一個URI:http://127.0.0.1/mvc/shxt/1001
。
在Spring MVC中能夠在方法參數上使用@PathVariable
標註,將其與URI模式中的參數綁定起來:
瀏覽器訪問路徑以下: http://127.0.0.1:8001/mvc/shxt/1001
package com.hanpang.web;
@Controller//告知其是一個控制器
@RequestMapping("/shxt")
public class Demo03Controller {
@RequestMapping("/{userId}")
public ModelAndView test01(@PathVariable String userId) {
System.out.println("獲取佔位符的值:"+userId);
return null;
}
}
複製代碼
會在控制檯輸出: 獲取佔位符的值:1001
URI模式"/shxt/{userId}
"定義了一個變量,名爲userId
。當控制器處理這個請求的時候,userId
的值就會被URI模式中對應部分的值所填充。好比說,若是請求的URI是/userId/1001
,此時變量userId
的值就是1001
。
若是形參id跟佔位符{userId}不一致
爲了處理@PathVariables
標註,Spring MVC必須經過變量名來找到URI模式中相對應的變量。能夠在標註中直接聲明:
package com.hanpang.web;
@Controller//告知其是一個控制器
@RequestMapping("/shxt")
public class Demo03Controller {
@RequestMapping("/{userId}")
public ModelAndView test01(@PathVariable(name="userId") String id) {
System.out.println("獲取佔位符的值:"+id);
return null;
}
}
複製代碼
一個方法能夠擁有任意數量的@PathVariable標註:
package com.hanpang.web;
@Controller//告知其是一個控制器
@RequestMapping("/shxt")
public class Demo03Controller {
@RequestMapping("/{userId}/role/{roleKey}")
public ModelAndView test01(@PathVariable(name="userId") String id,@PathVariable String roleKey) {
System.out.println("userId:"+id);
System.out.println("roleKey:"+roleKey);
return null;
}
}
複製代碼
當@PathVariable
標註被應用於Map<String, String>
類型的參數上時,框架會使用全部URI模式變量來填充map。
package com.hanpang.web;
@Controller//告知其是一個控制器
@RequestMapping("/shxt")
public class Demo03Controller {
@RequestMapping("/{userId}/role/{roleKey}")
public ModelAndView test01(@PathVariable Map<String,String> map) {
System.out.println(map);
return null;
}
}
複製代碼
@PathVariable
能夠被應用於全部簡單類型的參數上,好比int、long、Date等類型。Spring會自動地幫你把參數轉化成合適的類型,若是轉換失敗,就拋出一個TypeMismatchException。若是須要處理其餘數據類型的轉換,也能夠註冊自定義的類。
帶正則表達式的URI模式[來自官網]
有時候可能須要更準確地描述一個URI模式的變量,好比:/spring-web/spring-web-3.0.5.jar
。要怎麼把它分解成幾個有意義的部分呢?
@RequestMapping
標註支持在URI模式變量中使用正則表達式。語法是{varName:regex}
,其中第一部分定義了變量名,第二部分就是所要應用的正則表達式。好比下面的代碼樣例:
@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String extension) {
// ......
}
}
複製代碼
除了URI模式外,@RequestMapping標註還支持Ant風格的路徑模式(如/myPath/*.do
等)。不只如此,還能夠把URI模式變量和Ant風格的glob組合起來使用(好比/owners/*/pets/{petId}
這樣的用法等)。