一、@RequestMapping注解
RequestMapping是一个用来处理请求地址映射的注解,Spring MVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求。当DispatcherServlet截获请求后,就通过控制器上的@RequestMapping提供的映射信息确定请求所对应的处理方法。
使用位置:在控制器的类定义以及方法处
类定义处:提供初步的请求映射信息,相对于web应用的根目录,表示类中的所有响应请求的方法都是以该地址作为父路径。
方法处:提供进一步的细分映射信息。相对于类定义处的URL。若在类定义处未标注@RequestMapping,则方法处标记的URL相对于WEB应用的根目录。
@RequestMapping有六个属性,具体介绍如下:
(1)value:指定请求的实际地址,指定的地址可以是具体地址、可以RestFul动态获取、也可以使用正则设置。
@Controller
@RequestMapping(value = "/user") //RequestMapping用来类上
public class UserController {
//RequestMapping用来方法上
@RequestMapping(value = "/login")
public void login(){
}
}
(2)method:指定请求的method类型, GET、POST、PUT、DELETE等。如下:
/**
* 请求的method必须是get
*/
@RequestMapping(value = "/test01", method = RequestMethod.GET)
public void test01(){
System.out.println("get方式访问");
}
/**
* 请求的method必须是delete
*/
@RequestMapping(value = "/test02", method = RequestMethod.DELETE)
public void test02(){
System.out.println("delete方式访问");
}
(3)params: 规定了页面发起请求时request中必须包含的参数值。
关于params的一些简单的表达式操作:
param:请求中必须包含param的请求参数。
!param:请求中必须不包含param的请求参数。
param!=value;请求中param的值必须不为value。
{“param1=value1”,”param2”}:请求中必须包含param1和param2的请求参数,且param1的值必须为value1。
示例如下:
@RequestMapping(value = "/paramTest01", params = "username")
public void paramTest01(){
System.out.println("参数中必须包含username的请求参数");
}
@RequestMapping(value = "/paramTest02", params = "username=tom")
public void paramTest02(){
System.out.println("参数中必须包含username的请求参数,并且值必须为tom");
}
@RequestMapping(value = "/paramTest03", params = "!address")
public void paramTest03(){
System.out.println("参数中必须不包含address的请求参数");
}
@RequestMapping(value = "/paramTest04", params = {"username=tom","age"})
public void paramTest04(){
System.out.println("参数中必须包含username和age的两个请求参数,并且username的值必须为tom");
}
(4)headers:规定了页面发起请求时request中必须包含的header值。
示例:通过User-Agent指定当浏览器为火狐时方可访问。
@RequestMapping(value = "/testHeader", headers = {"User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0"})
public void testHeader(){
System.out.println("火狐浏览器才能访问");
}
(5)consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html。
(6)produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
二、Spring中获取请求参数的注解
1、@PathVariable注解
(1)介绍:@PathVariable是Spring3.0的一个新功能,用于接收请求路径中占位符的值。它只支持一个属性value,类型是为String,代表绑定的属性名称。默认不传递时,绑定为同名的形参。
(2)语法:@PathVariable("xxx")通过 @PathVariable 可以将URL中占位符参数{xxx}绑定到处理器类的方法形参中
(3)案例
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/pathVariable01/3">@PathVariable指定URL变量名</a>
<a href="${pageContext.request.contextPath}/pathVariable01/tom/18k">@PathVariable定义多个URL变量</a>
</body>
</html>
/**
* @PathVariable指定URL变量名
* @param id
* @return
*/
@RequestMapping(value = "/pathVariable01/{id}")
public String pathVariable01(@PathVariable("id") Integer id){
System.out.println(id);
return "success";
}
/**
* 定义多个URL变量
* @param name
* @param age
* @return
*/
@RequestMapping(value = "/pathVariable01/{name}/{age}")
public String pathVariable02(@PathVariable(value = "name") String name, @PathVariable(value = "age") Integer age){
System.out.println("name is : " + name + ", age is : " + age);
return "success";
}
注意:
a.在index.jsp中请求的url写法应为:
<a href="${pageContext.request.contextPath}/pathVariable01/3">@PathVariable指定URL变量名</a>
错误写法:
<a href="${pageContext.request.contextPath}/pathVariable01/{3}">@PathVariable指定URL变量名</a>
b.PathVariable的value值必须和方法的入参名相同。
2、@RequestParam注解
(1)介绍:该注解是Spring MVC中用于接收用户发起请求时所携带的参数信息,用于控制器中处理请求的方法上。
(2)语法:
@RequestParam(value = "参数名", required = true/false, defaultValue = "默认值"
相当于Servlet中的request.getParameter("参数名");
参数介绍:
value:参数名称
required:该参数在用户发起请求的时候是否是必须的,true表示必须携带该参数,false表示非必须。默认值为true。
defaultValue:该参数的默认值,如果不指定,则为null。
示例:
@RequestParam(value = "name", required = false, defaultValue = "tom"
等价于:username = request.getParameter("name");
说明:用户发起请求时需要携带name参数,但也可以没有此参数,当该值没有赋值时,默认值为tom。
(3)案例
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/request01?name=tom">用户请求携带name参数</a>
<a href="${pageContext.request.contextPath}/request02?name=Jerry">name参数必须有</a>
<a href="${pageContext.request.contextPath}/request03?name=Mack">系统默认方式获取参数</a>
</body>
</html>
RequestTestController:
@Controller
public class RequestTestController {
/**
* 普通写法:用户发起请求时携带name参数
* @param name 用户名
* @return
*/
@RequestMapping(value = "/request01")
public String request01(@RequestParam("name") String name){
System.out.println(name);
return "success";
}
/**
* 用户发起请求时必须携带name参数,如果name为null,则其默认值为tom
* @param username
* @return
*/
@RequestMapping(value = "/request02")
public String request02(@RequestParam(value = "name", required = true, defaultValue = "tom") String username){
System.out.println(username);
return "success";
}
/**
* 系统默认方式获取请求参数:直接给方法的入参上写一个和请求参数名称相同的变量,这个变量就用来接收请求参数的值
* 若有值则为用户指定的值,若无值则为Null。
* @param name
* @return
*/
@RequestMapping(value = "/request03")
public String request03(String name){
System.out.println(name);
return "success";
}
}
说明:系统默认方式获取请求参数,直接给方法的入参写一个和请求参数名称相同的变量即可得到此值。如果使用RequestParam注解,则方法的入参和请求的参数名可以不一致,参考上述例子中的requesto2方法。
(4)RequestParam和PathVariable的区别
相同点:RequestParam和PathVariable都是用来处理前端传递过来的请求参数
不同点:RequestParam处理的是请求参数,是将对应请求路径下的请求参数值映射到处理器参数上。PathVariable处理的是路径变量,是将请求路径变量的值映射到处理器参数上。
举个例子:
若请求为/user?name=tom,则RequestParam获取到的是?之后的key-value,通过在Controller中的方法入参获取到参数的值。
若请求为/user/{name},则PathVariable获取的是路径上占位符的值,也就是{name}的值。
3、@RequestHeader注解
(1)介绍:获取请求的头信息。
(2)语法:
@RequestHeader(value = "参数名", required = true/false, defaultValue = "默认值"
相当于Servlet中request.getHeader("参数名");
示例:
@RequestHeader("User-Agent")
等价于:userAgent = request.getHeader("User-Agent");
参数介绍:
value:参数名称
required:该参数在用户发起请求的时候是否是必须的,true表示必须携带该参数,false表示非必须。默认值为true。
defaultValue:该参数的默认值,如果不指定,则为null。
(3)案例
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/requestHeader01">@RequestHeader使用1</a>
<a href="${pageContext.request.contextPath}/request02">@RequestHeader使用2</a>
</body>
</html>
@RequestMapping(value = "/requestHeader01")
public String requestHeader01(@RequestHeader("User-Agent") String userAgent){
System.out.println(userAgent);
return "success";
}
@RequestMapping(value = "/requestHeader02")
public String requestHeader02(@RequestHeader(value = "User-Agent", required = false) String userAgent){
System.out.println(userAgent);
return "success";
}
4、@CookieValue注解
(1)介绍:将请求的Cookie数据,映射到功能处理方法的参数上。
(2)语法
@CookieValue(value = "参数名", required = true/false, defaultValue = "默认值"
Servlet中的写法:
Cookie[] cookies = request.getCookies(); for(Cookie c : cookies){ if(c.getName().equals("cookieName")){ String value = c.getValue(); } }
示例:
@CookieValue("JSESSIONID")
等价于:
Cookie[] cookies = request.getCookies(); for(Cookie c : cookies){ if(c.getName().equals("JSESSIONID")){ String value = c.getValue(); } }
参数介绍:
value:参数名称
required:该参数在用户发起请求的时候是否是必须的,true表示必须携带该参数,false表示非必须。默认值为true。
defaultValue:该参数的默认值,如果不指定,则为null。
(3)案例
<a href="${pageContext.request.contextPath}/getCookie">@CookieValue使用</a>
@RequestMapping(value = "/getCookie")
public String getCookie(@CookieValue("JSESSIONID") String cookieVal){
System.out.println(cookieVal);
return "success";
}
5、Spring MVC中POJO对象的使用
前面介绍了Spring MVC中获取参数的几种方式,但是当参数过多时,这种一一对应的方式就会显得代码中很乱,解决这一问题就需要使用POJO进行多参数封装。Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值(通过属性的set方法)。使用如下:
(1)在index.jsp中创建表单
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="${pageContext.request.contextPath}/pojoUse">
姓名: <input type="text" name="name"><br>
性别: <input type="text" name="sex"><br>
年龄: <input type="text" name="age"><br>
电话: <input type="text" name="tel"><br>
家庭住址: <input type="text" name="address"><br>
<input type="submit" value="提交"><br>
</form>
</body>
</html>
说明:form表单中的提交按钮,其type应该为submit,如果type为button则无法访问到后台。因为自己的失误在这里折腾了很久,后面才发现这个问题。
(2)创建Teacher对象。
public class Teacher {
private String name;
private String sex;
private String age;
private String tel;
private String address;
public Teacher() {
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
", tel='" + tel + '\'' +
", address='" + address + '\'' +
'}';
}
}
(3)在Controller中使用POJO对象
@RequestMapping(value = "/pojoUse", method = RequestMethod.POST)
public String pojoUse(Teacher teacher){
System.out.println(teacher);
return "success";
}
此外,Spring MVC中还支持级联属性。现对上述代码进行修改。
(1)在form表单中加入book的信息。
<form method="post" action="${pageContext.request.contextPath}/pojoUse">
姓名: <input type="text" name="name"><br>
性别: <input type="text" name="sex"><br>
年龄: <input type="text" name="age"><br>
电话: <input type="text" name="tel"><br>
家庭住址: <input type="text" name="address"><br>
书名: <input type="text" name="book.bName"><br>
作者: <input type="text" name="book.bAuthor"><br>
价格: <input type="text" name="book.bPrice"><br>
<input type="submit" value="提交"><br>
</form>
(2)创建Book类。
public class Book {
private String bName;
private String bAuthor;
private Double bPrice;
public Book() {
}
public String getbName() {
return bName;
}
public void setbName(String bName) {
this.bName = bName;
}
public String getbAuthor() {
return bAuthor;
}
public void setbAuthor(String bAuthor) {
this.bAuthor = bAuthor;
}
public Double getbPrice() {
return bPrice;
}
public void setbPrice(Double bPrice) {
this.bPrice = bPrice;
}
@Override
public String toString() {
return "Book{" +
"bName='" + bName + '\'' +
", bAuthor='" + bAuthor + '\'' +
", bPrice=" + bPrice +
'}';
}
}
(3)在Teacher中添加Book属性,提供get和set方法,覆写toSring()。
private Book book;
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age='" + age + '\'' +
", tel='" + tel + '\'' +
", address='" + address + '\'' +
", book=" + book +
'}';
}
}
注意:
a.实体类中必须有无参构造的存在。
b.请求参数名和对象中的属性名要一致。
c.上面的表单中,如果输入中文则后台接受的数据会出现乱码。
解决方案:在web.xml中配置字符编码过滤器。
<!-- 字符编码过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- encoding:指定一个具体的字符集 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- forceEncoding:处理 response中的字符编码 -->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>