第2 章 @RequestMapping注解
2.1 @RequestMapping 映射请求注解
2.1.1 @RequestMapping 概念
1) SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些 URL 请求
2) 在控制器的类定义及方法定义处都可标注 @RequestMapping
- ① 标记在类上:提供初步的请求映射信息。相对于 WEB 应用的根目录
- ② 标记在方法上:提供进一步的细分映射信息。相对于标记在类上的 URL。
3) 若类上未标注 @RequestMapping,则方法处标记的 URL 相对于 WEB 应用的根目录
4) 作用:DispatcherServlet 截获请求后,就通过控制器上 @RequestMapping 提供的映射信息确定请求所对应的处理方法。
2.1.2 @ RequestMapping源码参考
open type打开RequestMapping
package org.springframework.web.bind.annotation;
@Target({ElementType.METHOD, ElementType.TYPE})//可以往方法和类型上标@
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {//可以看见interface前有个@
String[] value() default {};
RequestMethod[] method() default {};//映射请求方式
String[] params() default {}; // 请求参数
String[] headers() default {}; //请求头。在@RequestMapping中无需写?&
String[] consumes() default {};
String[] produces() default {};
}
SpringmvcHandler.java
----------从下往上看方法-----------
package com.atguigu.springmvc.handler;
// 前面设计的代码还有上节的index.jsp的等
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.atguigu.springmvc.beans.User;
@Controller
//@RequestMapping(value="/springmvc")
// 上句相对于web应用根目录。对类中所有方法都起作用。此时后面的方法映射变为/springmvc/testRequestMapping
public class SpringmvcHandler {
/**
* 测试原生的Servlet API
* @throws IOException
* @throws ServletException
*/
@RequestMapping("/testServletAPI")
public void testServletAPI(HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
System.out.println("request: " + request );
System.out.println("response: " + response );
// 转发
//request.getRequestDispatcher("/WEB-INF/views/success.jsp").forward(request, response);
// 重定向 将数据写给客户端
//response.sendRedirect("http://www.baidu.com");
response.getWriter().println("Hello Springmvc ");
}
/**
* POJO
*/
@RequestMapping("/testPOJO")
public String testPOJO(User user) {
System.out.println("user:" + user);
return "success";
}
/**
* @CookieValue 映射cookie信息到请求处理方法的形参中
*/
@RequestMapping("/testCookieValue")
public String testCookieValue(@CookieValue("JSESSIONID")String sessionId) {
System.out.println("sessionid:" + sessionId);
return "success";
}
/**
* @RequestHeader 将请求头信息映射到请求处理方法的形参中
*/
@RequestMapping("testRequestHeader")
public String testRequestHeader(
@RequestHeader("Accept-Language")String acceptLanguage) {
System.out.println("acceptLanguage:" + acceptLanguage);
return "success";
}
/**
* @RequestParam 映射请求参数到请求处理方法的形参
* 1. 如果请求参数名与形参名一致, 则可以省略@RequestParam的指定。
* 2. @RequestParam 注解标注的形参必须要赋值。 必须要能从请求对象中获取到对应的请求参数。
* 可以使用required来设置为不是必须的。
* 3. 可以使用defaultValue来指定一个默认值取代null
* 客户端的请求:testRequestParam?username=Tom&age=22
*/
@RequestMapping("/testRequestParam")
public String testRequestParam(
@RequestParam("username")String username,
@RequestParam(value="age",required=false,defaultValue="0")int age ) {
//web: request.getParameter() request.getParameterMap()
System.out.println(username + " , " + age);
return "success";
}
/**
* REST PUT
*/
@RequestMapping(value="/order",method=RequestMethod.PUT)
public String testRestPUT() {
System.out.println("REST PUT");
return "success";
}
/**
* REST POST
*/
@RequestMapping(value="/order",method=RequestMethod.POST)
public String testRestPOST() {
System.out.println("REST POST");
return "success";
}
/**
* REST DELETE
*/
@RequestMapping(value="/order/{id}",method=RequestMethod.DELETE)
public String testRestDELETE(@PathVariable("id")Integer id ) {
System.out.println("REST DELETE: " + id );
return "success";
}
/**
* REST GET
*/
@RequestMapping(value="/order/{id}",method=RequestMethod.GET)
public String testRestGET(@PathVariable("id")Integer id ) {
System.out.println("REST GET: " + id );
return "success";
}
/**
* 带占位符的URL
*
* 浏览器: http://localhost:8888/Springmvc01/testPathVariable/admin/1001
*/
@RequestMapping(value="/testPathVariable/{name}/{id}")
public String testPathVariable(@PathVariable("name")String name,
@PathVariable("id")Integer id ) {
System.out.println(name + " : " + id);
return "success";
}
/**
* @RequestMapping 映射请求参数 以及 请求头信息
*
* params : username=tom&age=22
* headers
*/
@RequestMapping(value="/testRequestMappingParamsAndHeaders",
params= {"username","age=22","!hh"},//要求接受到的参数key。不能有参数也加个! // 22是必须值,不是默认值 // 是要求,不是在这里赋值
headers= {"!Accept-Language"} // 请求头
)
public String testRequestMappingParamsAndHeaders() {
return "success";
}
/**
* @RequestMapping method 映射请求方式
* //<a ref>发送 的是get请求,要想发送post请求需要些<form>
可以写单个,也可以写数组{,}
*/
@RequestMapping(value="/testRequestMappingMethod",
method= {RequestMethod.POST,RequestMethod.GET}
)//要求请求方式是get,带带括号的是可以处理多种请求
public String testRequestMappingMethod() {
return "success";
}
/**
* @RequestMapping
*/
@RequestMapping(value="/testRequestMapping") //相对于web应用的根目录//如果类上没注解的话
public String testRequestMapping() {
return "success";
}
}
<a ref>
发送 的是get请求,要想发送post请求需要些<form>
2.2 RequestMapping 可标注的位置
2.2.1 实验代码
定义页面链接、控制器方法
index.jsp
<a href="springmvc/helloworld">test @RequestMapping</a>
HelloWorldController.java
@Controller //声明Bean对象,为一个控制器组件
@RequestMapping("/springmvc")
public class HelloWorldController {
/**
* 映射请求的名称:用于客户端请求;类似Struts2中action映射配置的,action名称
*1 使用@RequestMapping 注解来映射请求的 URL
*2 返回值会通过视图解析器解析为实际的物理视图,
* 对于 InternalResourceViewResolver 视图解析器,
* 会做如下的解析:
* 通过 prefix + returnVal + 后缀 这样的方式得到实际的物理视图, 然会做转发操作.
* /WEB-INF/views/success.jsp
*/
@RequestMapping(value="/helloworld")
public String helloworld(){
System.out.println("hello,world");
return "success"; //结果如何跳转呢?需要配置视图解析器
}
}
2.3 RequestMapping映射请求方式
2.3.1 标准的 HTTP 请求报头
2.3.2 映射请求参数、请求方法或请求头
1)@RequestMapping 除了可以使用请求 URL 映射请求外,还可以使用请求方法、请求参数及请求头映射请求
2)@RequestMapping 的参数:
- value【重点】:请求 URL,支持通配符,支持{xxx}等rest风格
- method【重点】:请求方法,如RequestMethod.POST
- params【了解】 :请求参数
- heads【了解】 :及请求头的映射条件
他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。
3)params 和 headers支持简单的表达式:
- param1: 表示请求必须包含名为 param1 的请求参数
- !param1: 表示请求不能包含名为 param1 的请求参数
- param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
- {“param1=value1”, “param2”}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1
@RequestMapping 的value还支持 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
2.3.3 实验代码
1) 定义控制器方法
@Controller
@RequestMapping("/springmvc")
public class SpringMVCController {
@RequestMapping(value="/testMethord",method=RequestMethod.POST)
public String testMethord(){
System.out.println("testMethord...");
return "success";
}
}
2) 以get方式请求
<a href="springmvc/testMethord">testMethord</a>
发生请求错误 ,因为我们的RequestMapping设置的请求方式是post,而超链接是get
3) 以POST方式请求
<form action="springmvc/testMethord" method="post">
<input type="submit" value="submit">
</form>
2.4 RequestMapping映射请求参数&请求头
2.4.1 RequestMapping_请求参数&请求头【了解】
//了解: 可以使用 params 和 headers 来更加精确的映射请求. params 和 headers 支持简单的表达式.
@RequestMapping(value="/testParamsAndHeaders",
params= {"username","age!=10"},
headers = { "Accept-Language=en-US,zh;q=0.8" })//代表必须要有language这个参数
public String testParamsAndHeaders(){
System.out.println("testParamsAndHeaders...");
return "success";
}
2.4.2 实验代码
1) 请求URL
<!--设置请求参数和请求头信息 -->
<a href="springmvc/testParamsAndHeaders">testParamsAndHeaders</a>
《》
2) 测试:使用火狐或Chrom浏览器debug测试
① 测试有参数情况(不正确):
<a href="springmvc/testParamsAndHeaders">testParamsAndHeaders</a>
警告: No matching handler method found for servlet request: path '/springmvc/testParamsAndHeaders', method 'GET', parameters map[[empty]]
以为没带参数
<a href="springmvc/testParamsAndHeaders?username=atguigu&age=10">testParamsAndHeaders</a>
警告: No matching handler method found for servlet request: path '/springmvc/testParamsAndHeaders', method 'GET', parameters map['username' -> array<String>['atguigu'], 'age' -> array<String>['10']]
虽然带了参数,但参数不正确
<a href="springmvc/testParamsAndHeaders?age=11">testParamsAndHeaders</a>
警告: No matching handler method found for servlet request: path '/springmvc/testParamsAndHeaders', method 'GET', parameters map['age' -> array<String>['11']]
少带了一个参数
② 测试有参数情况(正确):
<a href="springmvc/testParamsAndHeaders?username=atguigu&age=15">testParamsAndHeaders</a>
2.5 RequestMapping映射请求占位符PathVariable注解
2.5.1 @PathVariable
带占位符的 URL 是 Spring3.0 新增的功能,该功能在 SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:
URL 中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。
2.5.2 实验代码
1) 定义控制器方法
//@PathVariable 注解可以将请求URL路径中的请求参数,传递到处理请求方法的入参中
@RequestMapping(value="/testPathVariable/{id}")
public String testPathVariable(@PathVariable("id") Integer id){//url中的参数赋值给形参中
System.out.println("testPathVariable...id="+id);
return "success";
}//不需要名称完全对应,在PathVariable中对应就行
2) 请求链接
<!-- 测试 @PathVariable -->
<a href="springmvc/testPathVariable/1">testPathVariable</a>
什么是rest(下节讲):
localhost:8888/spring01/testReq/admin/123465
testReq后面跟的其实是两个参数
value="/testPathVariable/{name}/{id}"