REST简介
REST介绍
- REST(Representational State Transfer),表现形式状态转换。
- 优点:
- 隐藏资源的访问行为,无法通过地址得知对资源是何种操作。
- 书写简化。
RESTful介绍
注意事项
- 上述行为是约定方式,约定不是规范,可以打破,所以称REST风格,而不是REST规范。
- 描述模块的名称通常使用复数,也就是加s的格式描述,表示此类资源,而非单个资源,例如:users、books、accounts……
RESTful简单案例
问题导入
案例代码
做法:在Controller中定义方法时设定”http请求动作(请求方式)”和”设定请求参数(路径变量)”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @Controller public class UserController {
@RequestMapping(value = "/users",method = RequestMethod.POST) @ResponseBody public String save(){ System.out.println("user save..."); return "{'module':'user save'}"; }
@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE) @ResponseBody public String delete(@PathVariable Integer id){ System.out.println("user delete..." + id); return "{'module':'user delete'}"; }
@RequestMapping(value = "/users",method = RequestMethod.PUT) @ResponseBody public String update(@RequestBody User user){ System.out.println("user update..."+user); return "{'module':'user update'}"; }
@RequestMapping(value = "/users/{id}" ,method = RequestMethod.GET) @ResponseBody public String getById(@PathVariable Integer id){ System.out.println("user getById..."+id); return "{'module':'user getById'}"; }
@RequestMapping(value = "/users",method = RequestMethod.GET) @ResponseBody public String getAll(){ System.out.println("user getAll..."); return "{'module':'user getAll'}"; } }
|
@PathVariable介绍
- 名称:@PathVariable
- 类型:形参注解
- 位置:SpringMVC控制器方法形参定义前面。
- 作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应。
@RequestBody、@RequestParam、@PathVariable区别和应用
- 区别:
@RequestParam用于接收url地址传参或表单传参。
@RequestBody用于接收json数据。
@PathVariable用于接收路径参数,使用{参数名称}描述路径参数。 - 应用:
后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广。
如果发送非json格式数据,选用@RequestParam接收请求参数。
采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值。
REST开发
代码中的问题
以上截图中的代码和之前写的UserController中的方法类似,其中图中两个方法都有三处是有问题的,可以进行优化。存在的问题如下:
问题1:每个方法的@RequestMapping注解中都定义了访问路径/books,重复性太高。
问题2:每个方法的@RequestMapping注解中都要使用method属性定义请求方式,重复性太高。
问题3:每个方法响应json都需要加上@ResponseBody注解,重复性太高。
Rest快速开发
解决问题1:在Controller类上使用@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 25 26 27 28 29 30 31
| @Controller @RequestMapping("/books") public class BookController { @RequestMapping(method = RequestMethod.POST) public String save(@RequestBody Book book){ System.out.println("book save..." + book); return "{'module':'book save'}"; } @RequestMapping(value = "/{id}" ,method = RequestMethod.DELETE) public String delete(@PathVariable Integer id){ System.out.println("book delete..." + id); return "{'module':'book delete'}"; } @RequestMapping(method = RequestMethod.PUT) public String update(@RequestBody Book book){ System.out.println("book update..."+book); return "{'module':'book update'}"; } @RequestMapping(value = "/{id}" ,method = RequestMethod.GET) public String getById(@PathVariable Integer id){ System.out.println("book getById..."+id); return "{'module':'book getById'}"; }
@RequestMapping(method = RequestMethod.GET) public String getAll(){ System.out.println("book getAll..."); return "{'module':'book getAll'}"; } }
|
解决问题2:使用@GetMapping @PostMapping @PutMapping @DeleteMapping代替@RequestMapping(method=RequestMethod.XXX)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| @Controller @RequestMapping("/books") public class BookController {
@PostMapping public String save(@RequestBody Book book){ System.out.println("book save..." + book); return "{'module':'book save'}"; }
@DeleteMapping("/{id}") public String delete(@PathVariable Integer id){ System.out.println("book delete..." + id); return "{'module':'book delete'}"; }
@PutMapping public String update(@RequestBody Book book){ System.out.println("book update..."+book); return "{'module':'book update'}"; }
@GetMapping("/{id}") public String getById(@PathVariable Integer id){ System.out.println("book getById..."+id); return "{'module':'book getById'}"; }
@GetMapping public String getAll(){ System.out.println("book getAll..."); return "{'module':'book getAll'}"; } }
|
- 名称:@GetMapping @PostMapping @PutMapping @DeleteMapping
- 类型:方法注解
- 位置:基于SpringMVC的RESTful开发控制器方法定义上方。
- 作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,例如@GetMapping对应GET请求。
- 属性:
value(默认):请求访问路径。
解决问题3:在Controller类上使用@RestController注解,等同于@Controller与@ResponseBody两个注解组合功能。
1 2 3 4 5
| @RestController @RequestMapping("/books") public class BookController { }
|
- 名称:@RestController
- 类型:类注解
- 位置:基于SpringMVC的RESTful开发控制器类定义上方。
- 作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能。
案例:基于RESTful页面数据交互
案例效果
环境准备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class Book { private Integer id; private String type; private String name; private String description; }
public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { protected Class<?>[] getRootConfigClasses() { return new Class[0]; }
protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; }
protected String[] getServletMappings() { return new String[]{"/"}; } @Override protected Filter[] getServletFilters() { CharacterEncodingFilter filter = new CharacterEncodingFilter(); filter.setEncoding("UTF-8"); return new Filter[]{filter}; } }
@Configuration @ComponentScan({"edu.heuet.controller","edu.heuet.config"}) @EnableWebMvc public class SpringMvcConfig { }
|
代码实现
制作SpringMVC控制器,并通过PostMan测试接口功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| @RestController @RequestMapping("/books") public class BookController {
@PostMapping public String save(@RequestBody Book book){ System.out.println("book save ==> "+ book); return "{'module':'book save success'}"; }
@GetMapping public List<Book> getAll(){ System.out.println("book getAll is running ..."); List<Book> bookList = new ArrayList<Book>();
Book book1 = new Book(); book1.setType("计算机"); book1.setName("SpringMVC入门教程"); book1.setDescription("小试牛刀"); bookList.add(book1);
Book book2 = new Book(); book2.setType("计算机"); book2.setName("SpringMVC实战教程"); book2.setDescription("一代宗师"); bookList.add(book2);
Book book3 = new Book(); book3.setType("计算机丛书"); book3.setName("SpringMVC实战教程进阶"); book3.setDescription("一代宗师呕心创作"); bookList.add(book3);
return bookList; } }
|
设置对静态资源的访问放行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Configuration public class SpringMvcSupport extends WebMvcConfigurationSupport { @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/pages/**") .addResourceLocations("/pages/"); registry.addResourceHandler("/js/**") .addResourceLocations("/js/"); registry.addResourceHandler("/css/**") .addResourceLocations("/css/"); registry.addResourceHandler("/plugins/**") .addResourceLocations("/plugins/"); } }
|
前端页面通过异步提交访问后台控制器
1 2 3 4 5 6 7 8 9 10 11 12
| saveBook () { axios.post("/books",this.formData).then((res)=>{
}); },
getAll() { axios.get("/books").then((res)=>{ this.dataList = res.data; }); },
|