本篇我们来学习如何来配置一个action的url映射规则。
在上一节 Spring MVC 入门指南(二):@RequestMapping用法详解 中配置了一个@RequestMapping(value = "/user") 这表示该controller的所有action请求必须是以"/user"开始。
1.URL路径映射
1.1.对一个action配置多个URL映射:
/**
* Created by Ray on 2018/4/17 0017.
*/
@Controller
@RequestMapping(value = "/user")
public class UserController {
@RequestMapping(value = {"/login","/hello"})
public String login(){
return "success";
}
}
@RequestMapping(value = {"/login","/hello"}) ,这表示对该action配置了/login和/hello两个映射 , 运行测试 , 如下 :
可以看到/login 和 /hello 请求都成功匹配
1.2.URL请求参数映射
这里使用到@PathVariable 映射 URL 绑定占位符:
1)带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
2)通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。
/**
* Created by Ray on 2018/4/17 0017.
*/
@Controller
@RequestMapping(value = "/user")
public class UserController {
/**
* URL请求参数映射
* @param id
* @return ModelAndView
*/
@RequestMapping(value = "/detail/{id}",method = RequestMethod.GET)
public ModelAndView getDetail(@PathVariable(value = "id") Integer id){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("id",id);
modelAndView.setViewName("detail");
return modelAndView;
}
}
其中RequestMapping(value = "/detail/{id}"), 中的{id}为占位符, 表示可以映射请求为/detail/xxxx 的URL, 如: /detail/123等等.
方法的参数@PathVariable(value = "id") Integer id 用于将URL中占位符所对应的变量映射到参数id上, 并指定变量的类型, 否则报错.
在views中添加detail.jsp视图, 用于将获取到的id值展现出来, 视图内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>标题</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
${id}
</body>
</html>
运行测试(一), 请求URL地址: http://localhost:8080/StringMVC/user/detail/123
运行测试(二), 请求URL地址: http://localhost:8080/StringMVC/user/detail/Ray
1.3.URL通配符映射
通配符有"?" 和 "*"两个字符. 其中 "?" 表示匹配1个字符, "*" 表示匹配多个字符, "**" 表示匹配0个或多个路径.
例如:
"/user/index?"可以匹配"/user/indexA"、"/user/indexB",但不能匹配"/user/index"、"/user/indexAA";
"/user/index*"可以匹配"/user/index"、"/user/indexA"、"/user/indexAA"但不能匹配"/user/index/A";
"/user/index/*"可以匹配"/user/index/"、"/user/index/A"、"/user/index/AA"、"/user/index/AB"但不能匹配"/user/index"、"/user/index/A/B";
"/user/index/**"可以匹配"/user/index/"下的多有子路径,比如:"/user/index/A/B/C/D";
如果现在有"/user/login"和"/user/*",如果请求地址为"/user/login"那么将如何匹配?Spring MVC会按照最长匹配优先原则(即和映射配置中哪个匹配的最多)来匹配,所以会匹配"/user/login",下面来做测试:
/**
* Created by Ray on 2018/4/17 0017.
*/
@Controller
@RequestMapping(value = "/user")
public class UserController {
@RequestMapping(value = {"/login","/hello"})
public String login(){
return "success";
}
/**
* URL通配符映射
* @return ModelAndView
*/
@RequestMapping(value = "/*",method = RequestMethod.GET)
public ModelAndView urlTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("404");
return modelAndView;
}
}
在views文件夹中新加一个视图404.jsp,为了和success.jsp做区别404.jsp的内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>url</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<h1>哈哈哈哈~ 404错误!</h1>
</body>
</html>
请求http://localhost:8080/StringMVC/user/login查看结果:
请求http://localhost:8080/StringMVC/user/Ray查看结果:
1.4.URL正则表达式映射
Spring MVC支持正则表达式方式的映射配置
/**
* Created by Ray on 2018/4/17 0017.
*/
@Controller
@RequestMapping(value = "/user")
public class UserController {
/**
* URL正则表达式映射
* @return ModelAndView
*/
@RequestMapping(value = "/reg/{name:\\w+}-{age:\\d+}",method = RequestMethod.GET)
public ModelAndView REGuRLtest(@PathVariable(value = "name")String name,@PathVariable(value = "age")Integer age){
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("name",name);
modelAndView.addObject("age",age);
modelAndView.setViewName("regurltest");
return modelAndView;
}
}
在views文件夹中新加一个视图regurltest.jsp内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>标题</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<h2>${name}-${age}</h2>
</body>
</html>
请求http://localhost:8080/StringMVC/user/reg/Ray-18 查看结果:
请求http://localhost:8080/StringMVC/user/reg/Ray-ray 查看结果:
2.限制action所接受请求的参数:
我们可以为某个action指定映射的请求中必须包含某参数, 或必须不包含某参数, 或者某参数必须等于某个值, 或者某参数必须不等于某个值 等限制.
2.1.指定映射请求必须包含某参数:
/**
* Created by Ray on 2018/4/17 0017.
*/
@Controller
@RequestMapping(value = "/user")
public class UserController {
/**
* URL通配符映射
* @return ModelAndView
*/
@RequestMapping(value = "/*",method = RequestMethod.GET)
public ModelAndView urlTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("404");
return modelAndView;
}
/**
* 指定映射请求必须包含某参数
* @return ModelAndView
*/
@RequestMapping(value = "/paramstest",params = "example",method = RequestMethod.GET)
public ModelAndView paramsTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("paramstest");
return modelAndView;
}
}
在views文件夹中新加一个视图paramstest.jsp内容如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>标题</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
</head>
<body>
<h1>paramstest</h1>
</body>
</html>
请求http://localhost:8080/StringMVC/user/paramstest
查看结果:
这里可以看到没有找到paramstest这个action结果还是映射到了404这个action。
请求http://localhost:8080/StringMVC/user/paramstest?example查看结果:
这次可以看到请求映射到了paramstest这个action。
2.2.指定映射请求必须不包含某参数:
/**
* Created by Ray on 2018/4/17 0017.
*/
@Controller
@RequestMapping(value = "/user")
public class UserController {
/**
* URL通配符映射
* @return ModelAndView
*/
@RequestMapping(value = "/*",method = RequestMethod.GET)
public ModelAndView urlTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("404");
return modelAndView;
}
/**
* 指定映射请求必须不包含某参数
* @return ModelAndView
*/
@RequestMapping(value = "/paramstest",params = "!example",method = RequestMethod.GET)
public ModelAndView paramsTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("paramstest");
return modelAndView;
}
}
重新请求http://localhost:8080/StringMVC/user/paramstest?example查看结果:
2.3.指定映射请求中或者某个参数必须等于某个值:
/**
* Created by Ray on 2018/4/17 0017.
*/
@Controller
@RequestMapping(value = "/user")
public class UserController {
/**
* URL通配符映射
* @return ModelAndView
*/
@RequestMapping(value = "/*",method = RequestMethod.GET)
public ModelAndView urlTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("404");
return modelAndView;
}
/**
* 指定映射请求必须等于某参数
* @return ModelAndView
*/
@RequestMapping(value = "/paramstest",params = "name=Ray",method = RequestMethod.GET)
public ModelAndView paramsTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("paramstest");
return modelAndView;
}
}
请求http://localhost:8080/StringMVC/user/paramstest?name=Ray查看结果:
2.3.指定映射请求中或者某个参数必须不等于某个值:
/**
* 指定映射请求必须不等于某参数
* @return ModelAndView
*/
@RequestMapping(value = "/paramstest",params = "name!=Ray",method = RequestMethod.GET)
public ModelAndView paramsTest(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("paramstest");
return modelAndView;
}
3.限制action所接受的请求方式(get或post):
3.1.通过 @RequestMapping(value="/login",method=RequestMethod.GET) 来指定 login()方法 仅处理通过 GET 方式发来的请求
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login", method=RequestMethod.GET)
public String login() {
return "success";
}
}
这时,如果浏览器发来的请求不是GET的话,将收到浏览器返回的错误提示,也就是得通过链接的方式而不是表单的方式:
<a href="user/login>User Login</a>
3.2.通过 @RequestMapping(value="/login",method=RequestMethod.POST) 来指定 login()方法 仅处理通过 POST 方式发来的请求
@Controller
@RequestMapping(path = "/user")
public class UserController {
@RequestMapping(path = "/login", method=RequestMethod.POST)
public String login() {
return "success";
}
}
这时,必须通过表单的方式发送请求,否则将收到浏览器返回的错误提示
<form action="user/login" method="post">
<input type="submit" value="使用Post发送请求"/>
</form>
3.3.由于在 RequestMapping 注解类中 method() 方法返回的是 RequestMethod 数组,所以可以给 method 同时指定多个请求方式,例如:
@Controller
@RequestMapping(path = "/user")
public class UserController {
// 该方法将同时接收通过GET和POST方式发来的请求
@RequestMapping(path = "/login", method={RequestMethod.POST,RequestMethod.GET})
public String login() {
return "success";
}
}