本文基于SpringMVC的helloworld项目来讲解演示。
1. 映射请求
1.1 @RequestMapping 映射请求
Spring MVC 使用 @RequestMapping 注解为控制器指定可以处理哪些 URL 请求,其在控制器的类定义及方法定义处都可标注。
- 类定义处:提供初步的请求映射信息,相对于 WEB 应用的根目录;
- 方法处:提供进一步的细分映射信息,相对于类定义处的 URL。若类定义处未标注 @RequestMapping,则方法处标记的 URL 相对于WEB 应用的根目录。
下面演示一下在注解@RequestMapping在类上的使用。
首先在com.shoto.springmvc.handlers包下创建如下类,具体如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
"/springmvc")//在类上使用映射请求注解 (
public class SpringMVCTest {
private final static String SUCCESS = "success";
"/testRequestMapping") (
public String testRequestMapping() {
System.out.println("testRequestMapping");
return SUCCESS;
}
}在index.jsp添加如下代码以实现访问。
1
<a href="springmvc/testRequestMapping.action">testRequestMapping</a><br/>
如果在类上没有使用@RequestMapping(“/springmvc”),那么如下代码可以写成如下的形式:
1 | <a href="testRequestMapping.action">testRequestMapping</a><br/> |
1.2 映射请求参数、请求方法和请求头
- @RequestMapping 除了可以使用请求 URL 映射请求外,还可以使用请求方法、请求参数及请求头映射请求
- @RequestMapping 的 value、method、params 及 heads分别表示请求 URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。
- params 和 headers支持简单的表达式:
- param1: 表示请求必须包含名为 param1 的请求参数
- !param1: 表示请求不能包含名为 param1 的请求参数
- param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
- {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2
的两个请求参数,且 param1 参数的值必须为 value1
1.2.1 映射请求方法(常用)
在SpringMVCTest类中添加如下方法:
1
2
3
4
5
6
7
8/**
* 使用method来指定请求方式
*/
"testMethod",method=RequestMethod.POST) (value=
public String testMethod() {
System.out.println("testMethod");
return SUCCESS;
}在index.jsp中添加如下语句进行响应测试
1
2
3<form action="springmvc/testMethod.action" method="post">
<input type="submit" name="testMethod"/>
</form>
注意:@RequestMapping中若未指明method属性,那么默认情况下则对于所有请求都会响应。
1.2.2 映射请求头
- 在SpringMVCTest类中添加如下方法:
1
2
3
4
5"testHeaders", headers= {"Accept-Language=en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7"}) (value=
public String testHeaders() {
System.out.println("testHeaders");
return SUCCESS;
}
需要注意的是Accept-Language后面跟的是等号,而不是冒号。
- 在index.jsp中添加如下语句进行响应测试
1
<a href="springmvc/testHeaders.action">testRequestHeaders</a><br/>
1.2.3 映射请求参数
在SpringMVCTest类中添加如下方法:
1
2
3
4
5"testRequestParams", params= {"username","age!=10"}) (value=
public String testRequestParams() {
System.out.println("testRequestParams");
return SUCCESS;
}在index.jsp中添加如下语句进行响应测试
1
<a href="springmvc/testRequestParams.action?username=abc&age=11">testRequestParams</a><br/>
1.3 Ant 风格的 URL
@RequestMapping 还支持 Ant 风格的 URL,Ant 风格资源地址支持 3 种匹配符:
- ?:匹配文件名中的一个字符
- *:匹配文件名中的任意字符
- : 匹配多层路径
示例:
- /user//createUser: 匹配/user/*aaa/createUser、/user/bbb**/createUser 等 URL
- /user//createUser: 匹配/user/createUser、/user/aaa/bbb**/createUser 等 URL
- /user/createUser??: 匹配/user/createUseraa、/user/createUserbb 等 URL
下面以*为例,代码示例如下:
在SpringMVCTest类中添加如下方法:
1
2
3
4
5"testAntPath/*/abc") (value=
public String testAntPath() {
System.out.println("testAntPath");
return SUCCESS;
}在index.jsp中添加如下语句进行响应测试
1
<a href="springmvc/testAntPath/nn/abc.action">testAntPath</a><br/>
2. 请求参数
2.1 @PathVariable 映射 URL 绑定的占位符
带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义。所谓的REST的具体含义如下所示:
举例:简单地说就是:如一超链接文本(资源)以html格式显示在页面上(表现层),点击超链接文本时会向服务器的发送GET请求获取数据,这个过程服务器端则发生了“状态转化”。
我们可以通过 @PathVariable 将 URL 中占位符参数绑定到控制器处理方法的入参中。
比如我们在SpringMVCTest定义如下方法,其实现了将占位符id绑定到控制器处理方法testPathVariable的参数id中。
1 | "/testPathVariable/{id}") (value= |
接着在index.jsp中编写如下代码,并传入参数1,即testPathVariable方法的id值。
1 | <a href="springmvc/testPathVariable/1.action">testPathVariable</a><br/> |
2.2 使用 HiddenHttpMethodFilter 过滤器
浏览器 form 表单只支持 GET与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器HiddenHttpMethodFilter,可以将这些POST请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与DELETE 请求。
首先需要进行过滤器的配置,在web.xml进行如下配置:
1
2
3
4
5
6
7
8
9<!-- 配置HiddenHttpMethodFilter,可以把POST请求转化为DELETE请求和PUT请求 -->
<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>在SpringMVCTest类中添加如下方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23"/testRest/{id}", method=RequestMethod.PUT) (value=
public String testRestPut(@PathVariable("id") Integer id) {
System.out.println("testRest PUT:" + id);
return SUCCESS;
}
"/testRest/{id}", method=RequestMethod.DELETE) (value=
public String testRestDelete(@PathVariable("id") Integer id) {
System.out.println("testRest DELETE:" + id);
return SUCCESS;
}
"/testRest", method=RequestMethod.POST) (value=
public String testRestPost() {
System.out.println("testRest POST");
return SUCCESS;
}
"/testRest/{id}", method=RequestMethod.GET) (value=
public String testRestGet(@PathVariable("id") Integer id) {
System.out.println("testRest GET:" + id);
return SUCCESS;
}然后在index.jsp中添加如下语句进行响应测试
1
2
3
4
5
6
7
8
9
10
11
12<form action="springmvc/testRest/1.action" method="post">
<input type="hidden" name="_method" value="PUT"/>
<input type="submit" value="TestRest PUT"/>
</form>
<form action="springmvc/testRest/1.action" method="post">
<input type="hidden" name="_method" value="DELETE"/>
<input type="submit" value="TestRest DELETE"/>
</form>
<form action="springmvc/testRest.action" method="post">
<input type="submit" value="TestRest POST"/>
</form>
<a href="springmvc/testRest/1.action">testRest GET</a><br/>
注意:这里使用到了隐藏表单,value的值为对应的提交方法,而name的值为_method。我们可以查看HiddenHttpMethodFilter的源码,具体如下示:
即过滤器会根据表单的name的值_method去获取对应的value,然后做对应的过滤操作。
2.3 使用 @RequestParam 绑定请求参数值
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法。
代码示例如下:
- 在SpringMVCTest类中添加如下方法:
1
2
3
4
5
6"/testRequestParam") (value=
public String testRequestParam(@RequestParam(value="username") String un,
@RequestParam(value="age", required=false, defaultValue="0") int age) {
System.out.println("username:" + un + " age:" + age);
return SUCCESS;
}
注意:value:参数名;required:是否必须。默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常;defaultValue:默认值。基本数据类型必须要赋予默认值,因为不能使用null值表示。
- 在index.jsp中添加如下语句进行响应测试
1
<a href="springmvc/testRequestParam.action?username=abc">testRest RequestParam</a><br/>
2.4 使用 @RequestHeader 绑定请求报头的属性值
请求头包含了若干个属性,服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中。
代码示例如下:
在SpringMVCTest类中添加如下方法:
1
2
3
4
5
6"/testRequestHeader") (value=
public String testRequestHeader(@RequestHeader(value="Accept-Language") String al) {
System.out.println("Accept-Language:" + al);
//输出Accept-Language:en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7
return SUCCESS;
}在index.jsp中添加如下语句进行响应测试
1
<a href="springmvc/testRequestHeader.action">testRequestHeader</a><br/>
注意:@RequestHeader与@RequestParam相似,都有required等属性。
2.5 使用 @CookieValue 绑定请求中的 Cookie 值
@CookieValue 可让处理方法入参绑定某个 Cookie 值。
在SpringMVCTest类中添加如下方法:
1
2
3
4
5
6"/testCookieValue") (value=
public String testCookieValue(@CookieValue(value="JSESSIONID") String sessionId) {
//输出:session id:8CBD7E8DE6851D48ACB806C4B020C6FB
System.out.println("session id:" + sessionId);
return SUCCESS;
}在index.jsp中添加语句进行响应测试
注意:@CookieValue与@RequestParam相似,都有required等属性。
2.6 使用 POJO 对象绑定请求参数值
Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值,并将POJO对象放入请求域中。支持级联属性。
代码示例如下:
- 首先在com.shoto.springmvc.entities下创建两个实体类,具体代码如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public class User {
private String uid;
private String username;
private String password;
private Integer age;
private Address address;
public User() {
super();
}
public User(String uid, String username, String password, Integer age, Address address) {
super();
this.uid = uid;
this.username = username;
this.password = password;
this.age = age;
this.address = address;
}
//getter,setter,toString
}
1 | public class Address { |
在SpringMVCTest类中添加如下方法:
1
2
3
4
5"/testPOJO",method=RequestMethod.POST) (value=
public String testPOJO(User user) {
System.out.println(user);
return SUCCESS;
}在index.jsp中添加如下语句进行响应测试
1
2
3
4
5
6
7
8
9<form action="springmvc/testPOJO.action" method="POST">
uid:<input type="text" name="uid"/><br/>
username:<input type="text" name="username"/><br/>
password:<input type="password" name="password"/><br/>
age:<input type="text" name="age"/><br/>
province:<input type="text" name="address.province"/><br/>
city:<input type="text" name="address.city"/><br/>
<input type="submit" name="确定"/>
</form>
2.7 使用 Servlet API 作为参数
SpringMVC 的 Handler 方法可以接收如下 ServletAPI 类型的参数:
HttpServletRequest、HttpServletResponse、HttpSession、java.security.Principal、 Locale、InputStream、OutputStream、Reader、Writer。
下面演示一下一些API的使用。
同样地,需要在SpringMVCTest定义如下方法,具体代码如下所示:
1
2
3
4
5
6
7
8
9
10
11"/testServletAPI") (value=
public void testServletAPI(HttpServletRequest req, HttpServletResponse resp, Writer out) throws IOException {
System.out.println("HttpServletRequest:" + req);
System.out.println("HttpServletResponse:" + resp);
/*
* 输出:
* HttpServletRequest:org.apache.catalina.connector.RequestFacade@133beef9
* HttpServletResponse:org.apache.catalina.connector.ResponseFacade@2b695474
*/
out.write("hello SpringMVC!");//会在页面上显示
}在index.jsp中添加语句进行响应测试即可。