1. @RequestMapping注解
1.1. 介绍
这是一个为控制器指定可以处理哪些URL请求的注解。
1.2. 修饰
- 修饰类
- 修饰方法
1.3. 演示
1.3.1. 简单测试
1、新建一个TestController
com.misiai.controller.TestController
package com.misiai.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/test")
public class TestController {
private static final String SUCCESS = "success";
@RequestMapping("/map")
public String testMapping() {
System.out.println("Hello Test Mapping");
return SUCCESS;
}
}
说明:
- 我们新建了一个TestController类,并给其加上@Controller注解,让其被spring管理。
- 给类加上@RequestMapping("/test")注解,表示其类下的所有方法的处理URL都是/test的子路径。
- 我们定义了一个常量SUCCESS,其值是success,最终返回的是/WEB-INF/pages/success.jsp,是因为在applicationContext.xml配置了后端视图处理器:
<!--后端jsp文件配置--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/"/> <property name="suffix" value=".jsp"/> </bean>
- 当然,这需要我们新建success.jsp文件,路径:src/main/webapp/WEB-INF/pages/success.jsp
结果:
我们访问:
http://localhost:8080/spring_mvc_1_war_exploded/test/map
路径,就是在访问TestController的testMapping方法
结果:
控制台:
总结:
- 类定义处:提供初步的请求映射信息。相对于WEB应用的根目录
- 方法处:提供进一步的细分映射信息。相对于类定义处的URL。若类定义处未标注@RequestMapping,则方法处标记的URL相对于WEB应用的根目录
1.3.2. 指定请求方法
在http中,常见的我们有两种请求方法:GET和POST,当然实际不止,实际还有DELETE,PUT,PATCH等等。
那我们如何才能指定只有某个请求方法,才能访问该请求呢?
有点绕,什么意思?比如:只能POST方法才能访问我TestController类的testMap方法,该如何做?
很简单,给@RequestMapping加一个注解即可:
@RequestMapping(value = "/testMethod", method = RequestMethod.POST)
public String testMethod() {
return SUCCESS;
}
当然,我们普通浏览器是不能直接发出POST请求的,需要借助表单:
index.jsp
<form action="test/testMethod" method="post">
<input type="submit" value="Submit">
</form>
如果我们用普通方法访问:
1.3.3. 参数绑定路径
/**
* 测试请求参数
* 表示:携带有Username,且参数age!=18
*/
@RequestMapping(value = "/testParam", params = {"username", "age!=18"})
public String testParam() {
return SUCCESS;
}
测试:
1、如果age=10
http://localhost:8080/spring_mvc_1_war_exploded/test/testParam?username=kuan&age=10
正常,age=10
2、如果age=18
http://localhost:8080/spring_mvc_1_war_exploded/test/testParam?username=kuan&age=18
1.3.4. Header头信息
header头信息和参数意义,给@RequestMapping注解加上一个值(headers={})
1.3.5. 映射请求
Ant风格:
- ? 表示匹配任意一个字符
- * 表示匹配任意字符
- ** 表示匹配多层路径
测试:
@RequestMapping("/testAnt/*")
public String testAnt() {
return SUCCESS;
}
1.3.6. 绑定占位符
此举奠定了Spring支持RESTful风格的强有力支持!
@RequestMapping("/testPathVar/{id}")
public String testPathVar(@PathVariable("id") Integer id) {
System.out.println("testPathVar:" + id);
return SUCCESS;
}
在参数那里使用"{名称}",然后在方法参数那里使用@PathVariable("名称") Integer id
,即可绑定变量。
结果:
1.3.7. RESTFUL风格
1.3.7.1. 简介
restful风格简单来说,就是操作资源的方式方法。
如下:
- 获得资源,GET方式,后面跟id:https://www.misiai.com/article/1 获得id为1的资源
- 添加资源,POST方式,https://www.misiai.com/article/
- 删除资源,DELETE方式,https://www.misiai.com/article/1 删除id为1的资源
- 修改资源,PUT、PATCH方式,https://www.misiai.com/article/1 修改id为1的资源
以上,便是简单的理解方式!
1.3.7.2. SpringMVC中的restful
spring mvc中的restful其实前面已经说了,就是通过给@RequestMapping注解指定method值,需要提出来说的是:如何表示DELETE、PUT、PATCH等方法,因为在平常页面中,我们只能表示GET、POST方式。
其实很简单,表单依然是POST方法,我们只需要在表单中加入一个name="_method"的隐藏域,其值value="DELETE"等请求名
代码如下:
1、配置filter
关于filter的概念以后章节讲解,现在先使用:
web.xml
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2、代码
index.jsp
<form action="test/testRestful" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="Submit">
</form>
TestController
@RequestMapping(value = "/testRestful", method = RequestMethod.DELETE)
public String testRestful() {
System.out.println("DELETE请求方式");
return SUCCESS;
}
测试结果:
1.3.8. 请求参数绑定
注解:@RequestParam
/**
* 请求参数
*
* @return
*/
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam("username") String user, @RequestParam("age") Integer age) {
System.out.println("用户名:" + user + ", 年龄:" + age);
return SUCCESS;
}
解释:
访问该方法的路径:
http://localhost:8080/spring_mvc_1_war_exploded/test/testRequestParam?username=kuan&age=18
1、@RequestParam("username")中的username必须和URL中的“username”名称一致,@RequestParam("username")一致后,我们想要赋予的变量名就可以不一致了。如上的代码我们是user而不是username
2、对于@RequestParam还有个参数是:required,默认true,也即代表该参数必须要有才能匹配该方法。如果我们设置为false,那么必须后面的变量类型必须是包装类型(即Integer,而不能是int);
3、当然,如果不是包装类型,我们还必须设置成了false,那么还可以给@RequestParam的defalutValue设置一个"默认值"。
结果:
浏览器(POSTMAN)
控制台:
1.3.9. 请求头绑定
和请求参数绑定一样,我们也可以获取某个请求头。
代码:
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader(value = "kuan") String kuan) {
System.out.println("请求头kuan的值:" + kuan);
return SUCCESS;
}
结果:
解释:
1、由于我们使用了PostMan,所以我们可以自定义发送一个header头信息(kuan=misiai),建议您也在浏览器安装一个postman(插件市场上市postman安装即可)
2、和@RequestParam一样,@RequestHeader也有这些值:required,defaultValue。
1.3.10. 请求Cookie绑定
请求cookie也和前面两个一样,直接演示:
注解:@CookieValue("cookie_kuan")
代码:
/**
* 请求Cookie绑定
*
* @param cookie
* @return
*/
@RequestMapping("/testCookie")
public String testCookie(@CookieValue("JSESSIONID") String cookie) {
System.out.println("Cookie JSESSIONID的值:" + cookie);
return SUCCESS;
}
结果:
解释:
1、JSESSIONID是Tomcat服务器默认就有的一个cookie,所以我们这里直接获取了该cookie的值,就没有新建一个Cookie;
1.3.11. 实体Java类绑定
User.java
假设我们有一个实体类,User
有两个:username,age
并且也支持级联属性!
Address.java
有两个:province,city
package com.misiai.domain;
public class User {
private String username;
private Integer age;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", age=" + age +
", address=" + address +
'}';
}
}
package com.misiai.domain;
public class Address {
private String province;
private String city;
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Address{" +
"province='" + province + '\'' +
", city='" + city + '\'' +
'}';
}
}
index.jsp
<form action="test/testDomainParam" method="post">
<input type="text" name="username" value="kuan">
<input type="text" name="age" value="18">
<input type="submit" value="Submit">
</form>
结果:
解释:
1、级联属性,级联属性需要使用"对象.属性"来赋值。如:address.province和address.city
1.3.12. 使用Servlet API入参
在方法名中还可以使用原生的api
具体类型有:
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
例子:
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request, HttpServletResponse response) {
String kuan = request.getParameter("kuan");
System.out.println("Kuan:" + kuan);
return SUCCESS;
}
结果:
解释:
1、要使用HttpServletRequest,您需要导入servlet-api 依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.3</version>
</dependency>