@RequestMapping
该注解除了应用在方法,还可以应用在类上,此时该注解会作用于控制器类的所有处理器方法上,它会作为URL的第一级访问目录。
示例
@Controller
@RequestMapping(path = "/test")
public class HelloController {
@RequestMapping(path = "/hello")
public String sayHello() {
System.out.println("halo SpringMVC");
return "success";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<h2>Hello World!</h2>
<a href="test/hello">跳转示例</a>
</body>
</html>
运行跳转后的URL:
属性
(1)value:用于指定请求的URL,它和 path 属性的作用是一样的。它支持接收多个字符串,例如
@RequestMapping({"/hello", "/test"})
(2)method:指定请求的方式,例如RequestMethod.GET。
(3)params:用于指定限制请求参数的条件,它要求请求参数的key和value必须和指定的相同,否则不会执行逻辑方法。
示例
//请求参数必须有 accountName并且money 不能是 100;
@RequestMapping(path = "/hello", params = {"accountName", "moeny!100" })
public String sayHello() {
System.out.println("halo SpringMVC");
return "success";
}
请求的链接:
<a href="test/hello?accountName=aaa&money>100">删除账户,金额 100</a>
@RequestBody
该注解用于获取请求内容,内容的结构为:key=value&key=value...。
get请求方式不适用此注解。
属性
required:是否必须有请求体。默认值是:true。当取值为 true 时,get 请求方式会报错。如果取值为 false,get 请求得到是 null。
示例
@Controller
@RequestMapping(path = "/test")
public class HelloController {
@RequestMapping(path = "/RequestBody")
public String testRequestBody(@RequestBody(required = false)String body) {
System.out.println(body);
return "success";
}
}
请求方式
<form action="test/RequestBody" method="post">
用户名称:<input type="text" name="username" ><br/>
用户密码:<input type="password" name="password" ><br/>
用户年龄:<input type="text" name="age" ><br/>
<input type="submit" value="保存">
</form>
控制台输出:
@ResponseBody
在前面的控制层类中的处理逻辑方法中,我们返回的是视图名,此外我们可能只希望返回数据给前端而非页面。
@ResponseBody注解可以放在返回类型前面或方法上,它可以将返回值放在response体内
示例
@Controller
@RequestMapping(path = "/test")
public class HelloController {
@RequestMapping(path = "/ResponseBody")
@ResponseBody
public String testResponseBody(HttpServletRequest request) {
return "url:" + request.getRequestURI();
}
/* 或者写成这样:
@RequestMapping(path = "/ResponseBody")
public @ResponseBody String testResponseBody(HttpServletRequest request) {
return "url:" + request.getRequestURI();
}
*/
}
请求链接:
<a href="test/ResponseBody">测试ResponseBody</a>
显示页面为:
@RequestParam
把请求URL中指定名称的参数传给逻辑方法
属性
value:请求URL中参数对应的名称
required:请求参数中是否必须提供此参数。默认值为true,表示必须提供,如果不提供将报错。
示例
@Controller
@RequestMapping(path = "/test")
public class HelloController {
@RequestMapping(path = "/RequestParam")
public String testRequestParam(@RequestParam("uname") String uname,
@RequestParam(value = "age", required = false) Integer age) {
System.out.println(uname + " is " + age + "years old");
return "success";
}
}
请求链接:
<a href="test/RequestParam?uname=on1">测试RequestParam</a>
@PathVariable
该注解用于获取请求URL中的占位符,例如 test/PathVariable/on1 中的字符串on1。
属性
value:指定URL中占位符名称
required:请求参数中是否必须提供占位符。
示例
@Controller
@RequestMapping(path = "/test")
public class HelloController {
//如果方法参数名与占位符名相同,则可以去点value属性,例如此处就可以去掉。
@RequestMapping(path = "/PathVariable/{uname}")
public String testPathVariable(@PathVariable("uname") String uname) {
System.out.println(uname);
return "success";
}
}
请求链接
a href="test/PathVariable/on1">测试PathVariable</a><br>
@ModelAttribute
注释在方法上
被@ModelAttribute注释的方法会在此控制层类的每个方法执行前被执行,且该方法的返回值会被绑定到Model对象。该注释可以修饰有/无返回值的方法。
@Controller
@RequestMapping(path = "/test")
public class HelloController {
@RequestMapping(path = "/ModelAttribute")
public String testModelAttribute(User user) {
user.setUname("gua");
System.out.println(user);
return "success";
}
@ModelAttribute
public User getUserByID(Model model) {
//模拟从数据库查询得到User
User user = new User();
user.setAge(20);
user.setUname("on1");
user.setId(11);
return user; //等价于model.addAttribute("user",user);
}
}
请求链接:
<a href="test/ModelAttribute?id=11">测试ModelAttribute</a><br>
success页面
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>成功</title>
</head>
<body>
<h3>成功跳转到此页面</h3>
${user.id}
${user.uname}
${user.age}
</body>
</html>
页面显示输出:
控制台输出:
当注解指定属性名
当@ModelAttribute指定属性名时,方法的返回值同样被放在Model中,且对应的key值为属性名。
@Controller
@RequestMapping(path = "/test")
public class HelloController {
@RequestMapping(path = "/ModelAttribute")
public String testModelAttribute(User user, Model model) {
user.setUname("gua");
System.out.println(user);
return "success";
}
@ModelAttribute("myUser")
public User getUserByID() {
//模拟从数据库查询得到User
User user = new User();
user.setAge(20);
user.setUname("on1");
user.setId(11);
return user; //等价于model.addAttribute("user",user);
}
}
跳转到的success页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>成功</title>
</head>
<body>
<h3>成功跳转到此页面</h3>
${myUser.id}
${myUser.uname}
${myUser.age}
</body>
</html>
页面显示:
控制台输出:
@ModelAttribute和@RequestMapping注解同一个方法
此时@RequestMapping的value值一方面是作为请求的路由部分,另一方面则表示要跳转的视图名一部分;此时方法的返回值不再是跳转的视图名,而是作为键值对里的value放在model里,键值对的key值则是@ModelAttribute指定的属性名。
另外如果请求该Controller类的其他方法时,不会首先执行同时被这两个注解修饰的方法。
@Controller
@RequestMapping(path = "/test")
public class HelloController {
/*
此时要跳转的页面url是http://localhost:8080/test/ModelAttribute2
res-success作为键值对被放在model里
*/
@RequestMapping(path = "/ModelAttribute2")
@ModelAttribute("res")
public String testModelAttribute2() {
return "success";
}
}
跳转到的ModelAttribute2页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>成功</title>
</head>
<body>
<h3>成功跳转到此页面</h3>
${res}
</html>
此时的视图结构:
页面显示:
注释在参数上
当@ModelAttribute("key")注释在方法参数上时,它会从当前隐式的model对象中取出key值对应的value值,并将value值复制给被注释的方法参数上。
@Controller
@RequestMapping(path = "/test")
public class HelloController {
@ModelAttribute("myUser")
public User getUserByID(Model model) {
User user = new User();
user.setAge(20);
user.setUname("on1");
user.setId(11);
model.addAttribute("newStr", "sngu");
return user; //等价于model.addAttribute("user",user);
}
@RequestMapping(path = "/ModelAttribute3")
public String testModelAttribute3(@ModelAttribute("myUser") User user, @ModelAttribute("newStr") String str) {
System.out.println(user);
System.out.println(str);
return "success";
}
}
控制台输出:
页面显示:
如果此处@ModelAttribute没有指定属性值user,则会默认指定为User类的首字母小写user,而如果str也没有指定属性值,则为null。