SpringMVC
使用@RequestMapping映射请求
- SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求
- 在控制器的类定义及方法定义处都可标注
@RequestMapping- 类定义处:提供初步的请求映射信息。相对于WEB应用的根目录
- 方法处:提供进一步的细分映射信息。相对于类定义处的URL。若类定义处未标注@RequestMapping,则方法处标记的URL相对于WEB应用的根目录
- DispatcherServlet截获请求后,就通过控制器上@RequestMapping提供的映射信息确定请求所对应的处理方法。
- @RequestMapping在控制器的类定义及方法定义处都可标注
请求地址@RequestMapping("/springMVCTest") @Controller public class SpringMVCTest { private static final String SUCCESS = "success"; @RequestMapping("/testRequestMapping") public String testRequestMapping() { System.out.println("testRequestMapping"); return SUCCESS; } }
<a href="springMVCTest/testRequestMapping">testRequestMapping</a>
映射请求参数、请求方法或请求头
@RequestMapping
除了可以使用请求URL映射请求外,还可以使用请求方法、请求参数及请求头映射请求@RequestMapping
的value
、mathod
、params
及heads
分别表示请求URL、请求方法、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可以让请求映射更加精确化- params和headers支持简单的表达式:
param1
:表示请求必须包含名为param1
的请求参数!param1
:表示请求不能包含名为param1
的请求参数param1!=value1
:表示去请求包含名为param1
的请求参数,但其值不能为value1
{"param1=value1","param2"}
:请求必须包含名为param1
和param2
的两个请求参数、且param1
参数的值必须为value1
。
映射请求方法的测试(常用)
@RequestMapping("/springMVCTest")
@Controller
public class SpringMVCTest {
private static final String SUCCESS = "success";
/**
* 常用:使用method请求来指定请求方式
*/
@RequestMapping(value = "/testMethod",method = RequestMethod.POST)
public String testMethod(){
System.out.println("testMethod");
return SUCCESS;
}
}
<%-- 超链接为GET请求,而我们设置了请求方法为post,所以请求失败 --%>
<a href="springMVCTest/testMethod">testMethod</a>
<form action="springMVCTest/testMethod" method="post">
<input type="submit" value="testMethod"/>
</form>
映射请求参数和请求头的测试(了解)
/**
* 了解:可以使用params和headers来更加精确的映射请求。params和headers支持简单的表达式
*/
@RequestMapping(
value = "/testParamsAndHeaders",
params = {"username","age!=10"},
headers = {"Accept-Language=en-US,zh;q=0.9"}
)
public String testParamsAndHeaders(){
System.out.println("testParamsAndHeaders");
return SUCCESS;
}
<a href="springMVCTest/testParamsAndHeaders?username=luckyazrael&age=22">testParamsAndHeaders</a>
@RequestMapping还支持Ant风格的URL
- Ant风格资源地址支持三种匹配符
-?
:匹配文件名中的一个字符
-*
:匹配文件名中的任意字符
-**
:匹配多层路径 - @RequestMapping还支持Ant风格的URL
- /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
@RequestMapping(value = "/testAntPath/*/abc")
public String testAntPath(){
System.out.println("testAntPath");
return SUCCESS;
}
<a href="springMVCTest/testAntPath/aa/abc">testAntPath - aa</a>
<br/>
<a href="springMVCTest/testAntPath/bb/abc">testAntPath - bb</a>
两个地址均可访问成功
@PathVariable映射URL绑定的占位符
- 带占位符的URL是Spring3.0新增的功能,该功能在SpringMVC向REST目标挺近发展过程中具有里程碑的意义
- 通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中:URL中的{xxx}占位符可以通过@PathVariable(“xxx”)绑定到操作方法的入参中。
/**
* @PathVariable 可以来映射URL中的占位符到目标方法的参数中。
*/
@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){
System.out.println("testPathVariable:" + id);
return SUCCESS;
}
<a href="springMVCTest/testPathVariable/1">Test PathVariable</a>
REST
- REST:即Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用
- 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URL(统一资源定位符)指向它,每种资源对应一个特定的URL。要获取这个资源,访问他的URL就可以,因此URL即为每一个资源的独一无二的识别符。
- 表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式。
- 状态转化(State Transfer):每发出一个请求,就代表客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是“表现层状态转化”。具体说,就是HTTP协议里面,四个表现操作方式的动词:GET、POST、PUT、DELETE。他们分别对应四种基本操作:GET用来获取资源,POST用来新建资源、PUT用来更新资源,DELETE用来删除资源。
- 示例:
- /order/1 HTTP GET :得到id=1的order
- /order/1 HTTP DELETE :删除id=1的order
- /order/1 HTTP PUT :更新id=1的order
- /order HTTP POST :新增order
- HiddenHttpMethodFilter :浏览器form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,Spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求
/**
* Rest 风格的URL
* 以CRUD为例:
* 如何发送PUT请求和DELETE请求呢?
* 1. 需要配置org.springframework.web.filter.HiddenHttpMethodFilter
* 2. 需要发送POST请求
* 3. 需要在发送POST请求时携带一个 name="_method"的隐藏域,值value=PUT或DELETE
*
* 在SpringMVC的目标方法中如何得到id呢?
* 使用@PathVariable注解
**/
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.PUT)
public String testRestPut(@PathVariable Integer id){
System.out.println("testRest PUT:" + id);
return SUCCESS;
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.DELETE)
public String testRestDelete(@PathVariable Integer id){
System.out.println("testRest DELETE:" + id);
return SUCCESS;
}
@RequestMapping(value = "/testRest",method = RequestMethod.POST)
public String testRest(){
System.out.println("testRest POST");
return SUCCESS;
}
@RequestMapping(value = "/testRest/{id}",method = RequestMethod.GET)
public String testRest(@PathVariable Integer id){
System.out.println("testRest GET:" + id);
return SUCCESS;
}
在web.xml中配置org.springframework.web.filter.HiddenHttpMethodFilter
<!-- 配置org.springframework.web.filter.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>
<form action="springMVCTest/testRest/1" method="POST">
<input type="hidden" name="_method" value="PUT"/>
<input type="submit" value="testRest PUT"/>
</form>
<br/>
<form action="springMVCTest/testRest/1" method="POST">
<input type="hidden" name="_method" value="DELETE"/>
<input type="submit" value="testRest DELETE"/>
</form>
<br/>
<form action="springMVCTest/testRest" method="POST">
<input type="submit" value="testRest POST"/>
</form>
<br/>
<a href="springMVCTest/testRest/1">Test Rest GET</a>
请求处理方法签名
- SpringMVC通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的相应入参中。
- SpringMVC对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
- 必要时可以对方法及方法入参标注相应的注解(@PathVariable、@RequestParam、@RequestHeader等)、SpringMVC框架会将HTTP请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。
使用@RequestParam绑定请求参数值
- 在处理方法入参处使用@RequestParam可以把请求参数传递给请求方法
- value:参数名
- required:是否必须。默认为true,表示请求参数中必须包含对应的参数,若不存在,将抛出异常
/**
* @RequestParam 来映射请求参数
* value 值即请求参数的参数名
* required 该参数是否必须,默认为true
* defaultValue 请求参数的默认值
*/
@RequestMapping("/testRequestParam")
public String testRequestParam(@RequestParam(value = "username")String username,
@RequestParam(value = "age",required = false,defaultValue="0")int age){
System.out.println("testRequestParam:username=" + username +",age=" + age );
return SUCCESS;
}
使用@RequestHeader绑定请求报头的属性值
- 请求头包含了若干个属性,服务器可据此获知客户端的信息,通过@RequestHeader即可将请求头中的属性值绑定到处理方法的入参中
/**
* 了解:
* 映射请求头信息
* 用法同 @RequestParam
*/
@RequestMapping("/testRequestHeader")
public String testRequestHeader(@RequestHeader("Accept-Encoding") String encoding){
System.out.println("testRequestHeader:Accept-Encoding=" + encoding);
return SUCCESS;
}
使用@CookieValue绑定请求中的Cookie值
- @CookieValue可以让处理方法入参绑定某个Cookie值
/**
* 了解:
* @CookieValue 映射一个cookie值,属性同@RequestParam
*/
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue(value = "JSESSIONID",required = false) String jSessionId){
System.out.println("testCookieValue:JSESSIONID=" + jSessionId);
return SUCCESS;
}
使用POJO对象绑定请求参数值
- SpringMVC会按请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel等
@RequestMapping("/testPojo")
public String testPojo(User user){
System.out.println("testPojo:" + user);
return SUCCESS;
}
User类
public class User {
private String username;
private String password;
private String email;
private Integer age;
private Address address;
get/set/toString...
}
Address类
public class Address {
private String province;
private String city;
get/set/toString...
}
xxx.jsp
<form action="springMVCTest/testPojo" method="post">
username:<input type="text" name="username"/>
<br/>
password:<input type="password" name="password"/>
<br/>
email:<input type="text" name="email"/>
<br/>
age:<input type="text" name="age"/>
<br/>
city:<input type="text" name="address.city"/>
<br/>
province:<input type="text" name="address.province"/>
<br/>
<input type="submit" value="submit"/>
</form>
使用ServletAPI作为入参
MVC的Handler方法可以接受哪些ServletAPI类型的参数
- HttpServletRequest
- HttpServletResponse
- HttpSession
- java.security.Principal
- Locale
- InputStream
- OutputStream
- Reader
- Writer
/**
* 可以使用Servlet原生的API作为目标方法的参数
*/
@RequestMapping("/testServletAPI")
public void testServletAPI(HttpServletRequest request, HttpServletResponse response){
System.out.println("testServletAPI," + request + "," + response);
return SUCCESS;
}
<a href="springMVCTest/testServletAPI">Test ServletAPI</a>
以Writer为例
/**
* 可以使用Servlet原生的API作为目标方法的参数
*/
@RequestMapping("/testServletAPI")
public void testServletAPI(HttpServletRequest request, HttpServletResponse response, Writer out) throws IOException {
System.out.println("testServletAPI," + request + "," + response);
out.write("hello world");
//return SUCCESS;
}