目录

  1. @RequestMapping
    1. @RequestMapping源码
    2. 限定处理特定请求参数
    3. 限定处理特定请求头
  2. @ResponseBody
  3. @RequestBody
  4. @Controller与@RestController
  5. @PathVariable
  6. 获取请求参数注解
    1. 默认方式
    2. @RequestParam 方式
  7. @RequestHeader
  8. @CookieValue
  9. @SessionAttributes
  10. 附录

@RequestMapping

✨特点

  • @RequestMapping 注解指定对应的 URL 将由那种控制器执行
  • 标记在方法上:提供精确的映射
  • 标记在类上:提供简单的映射关系,通常仍需将注解标记在方法上
  • 若类上未标注@RequestMapping,则方法处标记的 URL 相对于 WEB 应用的根目录

🎶 DispatcherServlet 截获请求后,就通过控制器上 @RequestMapping 提供的映射信息确定请求所对应的处理方法

1
2
3
4
5
6
7
8
9
@Controller
@RequestMapping(value = {"/hello"})
public class FirstController {
@RequestMapping(value = {"/index"}, method = {RequestMethod.GET})
public String index() {
System.out.println("the page of hello had visited");
return "success";
}
}

🎶需要访问工程路径/hello/index才能执行index()方法

@RequestMapping源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {

String name() default "";
//请求URL限定
@AliasFor("path")
String[] value() default {};

@AliasFor("value")
String[] path() default {};
//请求方法限定
RequestMethod[] method() default {};
//请求参数限定
String[] params() default {};
//请求头限定
String[] headers() default {};
//内容类型限定,规定请求头中的Content-Type字段
String[] consumes() default {};
//告诉浏览器返回的内容类型是什么,Content-Type
String[] produces() default {};
}

如果设定了多个参数,需要同时满足,才会执行对应的控制器,做到请求映射的精确控制

限定处理特定请求参数

1
2
3
4
5
6
7
8
9
@Controller
@RequestMapping(value = {"/hello"})
public class FirstController {
@RequestMapping(value = {"/index"}, method = {RequestMethod.GET}, params = {"username", "!password", "id=001", "gender!=male"})
public String index() {
System.out.println("the page of hello had visited");
return "success";
}
}

以下url可以成功执行index()方法

1
GET http://localhost:8080/hello/index?id=002&username=pineapple-man&gender=female

限定处理特定请求头

做到只有谷歌浏览器可以访问,其他浏览器均不能访问

1
2
3
4
5
@RequestMapping(value = {"/index"}, method = {RequestMethod.GET}, headers = {"User-Agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.72 Safari/537.36"})
public String index() {
System.out.println("the page of hello had visited");
return "success";
}

@ResponseBody

@Responsebody 表示该方法的返回结果直接写入 HTTP response body 中一般在异步获取数据时使用,在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。比如异步获取 json 数据,加上 @Responsebody 后,会直接返回 json 数据

1
2
3
4
5
6
@RequestMapping("/Item/{ItemId}")
@ResponseBody
public Item getItemById(@PathVariable Long id){
Item item=itemService.getItemById(id);
return item;
}

@RequestBody

@RequestBody 主要用来接收前端传递给后端的 json 字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是 POST 请求了,所以使用 @RequestBody 接收数据时,一般都用 POST 方式进行提交。在后端的同一个接收方法里,@RequestBody 与 @RequestParam 可以同时使用,@RequestBody 最多只能有一个,而@RequestParam()可以有多个

如果后端参数是一个对象,且该参数前是以@RequestBody 修饰的,那么前端传递 json 参数时,必须满足以下要求:

  • 后端@RequestBody 注解对应的类在将 HTTP 的输入流(含请求体)装配到目标类时,会根据 json 字符串中的 key 来匹配对应实体类的属性,如果匹配一致且 json 中的该 key 对应的值符合实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该类型
  • json 字符串中,如果 value 为""的话,后端对应属性如果是 String 类型的,那么接受到的就是"",如果是后端属性的类型是 Integer、Double 等类型,那么接收到的就是 null
  • json 字符串中,如果 value 为 null 的话,后端对应收到的就是 null
  • 如果某个参数没有 value 的话,在传 json 字符串给后端时,要么干脆就不把该字段写到 json 字符串中;要么写 value 时, 必须有值,null 或""都行

@Controller@RestController

1
2
3
4
5
6
7
8
9
10
11
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

@AliasFor(annotation = Controller.class)
String value() default "";

}
1
2
3
4
5
6
7
8
9
10
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

@AliasFor(annotation = Component.class)
String value() default "";

}

🎶 @RestController注解比@Controller注解多上@ResponseBody注解,作为直接的响应体进行返回

@PathVariable

@PathVariable注解映射 URL 绑定的占位符(在路径的任意地声明变量),通过@PathVariable可以将 URL 中占位符参数绑定到控制器处理方法的入参中

URL 中的 {xxx}占位符可以通过@PathVariable("xxx")绑定到操作方法的入参中

1
2
3
4
5
6
7
8
9
10
@Controller
@RequestMapping(value = {"/hello"})
public class FirstController {
@RequestMapping(value = {"/{index?}", "/index/*/?"}, method = {RequestMethod.GET})
public String index(@PathVariable("index?") String index) {
System.out.println("index = " + index);
System.out.println("the page of hello had visited");
return "success";
}
}

🎶访问/hello/index/hello/index1/hello/indexa均能得到响应

获取请求参数注解

SpringMVC 获取请求参数的两种方式:方法参数映射方式以及使用@Requestparam注解映射

默认方式

✨ 直接给方法入参上写一个和请求参数名相同的变量,这个变量就来接收请求参数的值,如果请求中带有此值,则能截获;如果请求中不带有此参数,默认为null

1
2
3
4
5
6
@RequestMapping(value = {"/users", "/users/*"}, method = {RequestMethod.GET})
public String getMethod(String username) {
System.out.println("username is " + username);
System.out.println("get");
return "success";
}
1
http://localhost:8080/users?username=1

@RequestParam 方式

用于获取请求参数,在处理方法入参时使用,可以把请求参数传递给请求方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";

@AliasFor("value")
String name() default "";

boolean required() default true;

String defaultValue() default ValueConstants.DEFAULT_NONE;
}

@RequestHeader

🎶 获取请求头中某个 key 的 value,如果请求头中没有这个值就会报错,可将请求头中的属性值绑定到处理方法的入参中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {

@AliasFor("name")
String value() default "";

@AliasFor("value")
String name() default "";

boolean required() default true;

String defaultValue() default ValueConstants.DEFAULT_NONE;

}
1
2
3
4
5
6
7
8
@RequestMapping(value = {"/users", "/users/*"}, method = {RequestMethod.GET})
public String getMethod(@RequestParam(value = "username", required = false) String username,
@RequestHeader(value = "User-Agent", required = false) String userAgent,
) {
System.out.println("username is " + username);
System.out.println("user-Agent is " + userAgent);
return "success";
}

@CookieValue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CookieValue {
@AliasFor("name")
String value() default "";

@AliasFor("value")
String name() default "";

boolean required() default true;

String defaultValue() default ValueConstants.DEFAULT_NONE;

}
1
2
3
4
5
6
7
8
@RequestMapping(value = {"/users", "/users/*"}, method = {RequestMethod.GET})
public String getMethod(@RequestParam(value = "username", required = false) String username,
@CookieValue(value = "JSESSIONID", required = false) String cookie
) {
System.out.println("username is " + username);
System.out.println("JSESSION ID is " + cookie);
return "success";
}

@SessionAttributes

1
2
3
4
5
6
7
8
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SessionAttributes {
String[] value() default {};
Class<?>[] types() default {};
}
1
2
3
4
5
//会将隐含模型中所有类型为 User.class 的属性添加到会话中
@SessionAttributes(types=User.class)
@SessionAttributes(value={“user1”, “user2”})
@SessionAttributes(types={User.class, Dept.class})
@SessionAttributes(value={“user1”, “user2”}, types={Dept.class})

附录

Spring @Controller and @RestController Annotations
Spring REST JSON Response Example
@Responsebody 与@RequestBody
@ResponseBody 的作用