我的建议从新练习一遍搭建的过程,若是感受麻烦你能够直接复制上一个工程,可是须要修改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}
这样的用法等)。