Spring Boot :@Controller和@RestController的区别、@RequestMapping说明
@RestController = @Controller + @ResponseBody
官方文档:
Spring Boot Controller
在 Spring Boot 中,@Controller 注解是专门用于处理 Http 请求处理的,是以 MVC 为核心的设计思想的控制层。@RestController 则是 @Controller 的衍生注解。
1. 原理
Spring Boot 是 Spring MVC 的简化版本,在 Spring MVC 的基础上实现了自动配置。
Spring MVC 通过一个叫 DispatcherServlet
前端控制器来拦截请求。而在 Spring Boot 中 使用自动配置把 DispatcherServlet
前端控制器自动配置到框架中。
2. 相关注解
在 Spring Boot 中使用到 @Controller 及相关的注解如下,主要分为三个层面进行,请求前,处理中,返回。
应用场景 | 注解 | 注解说明 |
---|---|---|
处理请求 | @Controller | 处理 Http 请求 |
处理请求 | @RestController | @Controller 的衍生注解 |
路由请求 | @RequestMapping | 路由请求 可以设置各种操作方法 |
路由请求 | @GetMapping | GET 方法的路由 |
路由请求 | @PostMapping | POST 方法的路由 |
路由请求 | @PutMapping | PUT 方法的路由 |
路由请求 | @DeleteMapping | DELETE 方法的路由 |
请求参数 | @PathVariable | 处理请求 url 路径中的参数 /user/{id} |
请求参数 | @RequestParam | 处理问号后面的参数 |
请求参数 | @RequestBody | 请求参数以json格式提交 |
返回参数 | @ResponseBody | 返回 json 格式 |
注意:
- @RestController 是 @Controller 的子集。
- @GetMapping、@PostMapping、@PutMapping、@DeleteMapping 是 @RequestMapping
的子集。
所以只需要掌握 @Controller 和 @RequestMapping 。
3. @Controller 与 @RestController 的区别
@RestController 是 @Controller 和 @ResponseBody 两个注解的结合体。
- @Controller 包括了 @RestController。
- @RestController是从Spring 4.0以后产生的,用来将json/xml数据发送到前台页面,而不是返回视图页面。
- @RestController加在类上面的注解,使得类里面的每个方法都将json/xml返回数据加返回到前台页面中;@Controller加在类上面的注解,使得类里面的每个方法都返回一个试图页面。
- @Controller和@ResponseBody(加在方法/类上面)一起使用,和@RestController的作用相同。后者是前两个注解的结合体。
@Controller
public class HelloController {
@GetMapping(value="/hello")
@ResponseBody
public String say(){//返回json 数据
return "gril";
}
@GetMapping(value="/hello1")
public String say1(){//返回视图
return "sys/index1";
}
}
@Controller
@ResponseBody
public class HelloController {
// 都返回json数据到页面
@GetMapping(value="/hello")
public String say(){
return "gril";
}
@GetMapping(value="/hello1")
public String say1(){
return "sys/index1";
}
}
@RestController的源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}
@RestController的编写方式依赖注解组合,@RestController被@Controller和@ResponseBody标注,表示@RestController具有两者的注解语义,因此在注解处理时@RestController比@Controller多具有一个@ResponseBody语义,这就是@RestController和@Controller的区别,也是@RestController的返回值为何都是经过转换的json的原因。
4. @Controller 与 @RestController的应用场景
-
@Controller 一般应用在有返回界面的应用场景下.
例如,管理后台使用了 thymeleaf 作为模板开发,需要从后台直接返回 Model 对象到前台,那么这时候就需要使用 @Controller 来注解。
-
@RestController 如果只是接口,那么就用 RestController 来注解.
例如前端页面全部使用了 Html、Jquery来开发,通过 Ajax 请求服务端接口,那么接口就使用 @RestController 统一注解。
5. @RequestMapping 说明
@RequestMapping 的源码:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
//指定请求的实际地址
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
//指定请求的method类型, GET、POST、PUT、DELETE等
RequestMethod[] method() default {};
//指定request中必须包含某些参数值是,才让该方法处理。
String[] params() default {};
//指定request中必须包含某些指定的header值,才能让该方法处理请求。
String[] headers() default {};
//指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
String[] consumes() default {};
//指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;
String[] produces() default {};
}
示例 | 说明 |
---|---|
@RequestMapping("/index") | 默认为 GET 方法的路由 /index |
@RequestMapping(value="/index",method = RequestMethod.GET) | 同上面一条 |
@RequestMapping(value="/add",method = RequestMethod.POST) | 路由为 /add 的 POST 请求 |
@RequestMapping(value="/add",method = RequestMethod.POST),consumes=“application/json” | 路由为 /add 的 POST 请求,但仅仅处理 application/json 的请求 |
@RequestMapping(value="/add",method = RequestMethod.POST),produces=“application/json” | 路由为 /add 的 POST 请求,强调返回为 JSON 格式 |
@RequestMapping(value="/add",method = RequestMethod.POST),params=“myParam=xyz” | 路由为 /add 的 POST 请求,但仅仅处理头部包括 myParam=xyz 的请求 |
@RequestMapping(value="/add",method = RequestMethod.POST),headers=“Referer=http://www.xyz.com/” | 路由为 /add 的 POST 请求,但仅仅处理 来源为 www.xyz.com 的请求 |
@RequestMapping 配置url映射
@RequestMapping此注解即可以作用在控制器的某个方法上,也可以作用在此控制器类上。
当控制器在类级别上添加@RequestMapping注解时,这个注解会应用到控制器的所有处理器方法上。处理器方法上的@RequestMapping注解会对类级别上的@RequestMapping的声明进行补充。
例1:@RequestMapping仅作用在处理器方法上
@RestController
public class HelloController {
@RequestMapping(value="/hello",method= RequestMethod.GET)
public String sayHello(){
return "hello";
}
}
以上代码sayHello所响应的url=localhost:8080/hello。
例1:@RequestMapping仅作用在类级别上
/**
* Created by wuranghao on 2017/4/7.
*/
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method= RequestMethod.GET)
public String sayHello(){
return "hello";
}
}
以上代码sayHello所响应的url=localhost:8080/hello,效果与例一一样,没有改变任何功能。
例3:@RequestMapping作用在类级别和处理器方法上
/**
* Created by wuranghao on 2017/4/7.
*/
@RestController
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(value="/sayHello",method= RequestMethod.GET)
public String sayHello(){
return "hello";
}
@RequestMapping(value="/sayHi",method= RequestMethod.GET)
public String sayHi(){
return "hi";
}
}
这样,以上代码中的sayHello所响应的url=localhost:8080/hello/sayHello;sayHi所响应的url=localhost:8080/hello/sayHi。
@RequestMapping中的method参数有很多中选择,一般使用get/post