SpringMVC开发RESTful接口
概念:
什么是REST?
REST是Representational State Transfer的缩写。翻译为"表现层状态转化",restful是一种接口设计风格,它不是一个协议,通常是基于HTTP协议的;
为什么需要这么一个风格呢?
RESTful的重点之一就是统一的接口命名规则;
每个开发者可能会有不同的接口风格,最常见的就类似于于getUserInfo,deleteUserInfo等等.....,但是这个纯粹是跟每个开发者的习惯有关,多人协同开发时就可能会产生问题,特别是前后台分离时,前台人员不得不填写大量各不相同的url来请求数据;
RESTful风格:
rest将每一个URI都看作是一个资源,这是一个概念,实际可以是一个图片,一条记录,一组记录都可以; 每一种请求方法都对应着对某个资源的操作,通常包含以下四种:
- GET 获取资源
- PUT 更新资源
- POST 提交资源
- DELETE 删除资源
假设我们将id为1的用户数据看做是一个资源,那么我们要在前台操作这个资源时就要向服务器发送能够定位这个资源的请求地址,如:http://localhost:8080/SSMDemo/user/1 ,通过URI找到资源后,我们还要告诉服务器我们要对这个资源进行什么样的操作,就通过HTTP的请求方法;如GET
简单的说:RESTful就是用URI来定位资源,在通过请求方法来定义要执行的操作;
目前而言完全按照RESTful来设计的网站并不多,亚马逊算是最早采用这种风格的网站之一,它的URL是像这样:https://www.amazon.cn/gp/product/B00MCW8R1S
RESTful的无状态性:
无状态约束使服务器的变化对客户端是不可见的,两次连续的请求中,客户端不依赖于同一台服务器,这使得服务器具备更好的伸缩性;
RESTful为系统带来的好处:
降低开发的复杂性,提高系统的可伸缩性,使得接口更加规范化;
URI与URL:
URL是统一资源标识 (只要能唯一标识一个资源就叫做URI)
URL是统一资源路径
URL属于URI的一种
SpringMVC中的RESTful
可以看出来,RESTful的变化在于,请求地址的处理,以及请求方法的定义;
我们有两个事情要做:
- 需要从URL中获取一些参数
- 使得同一个接口的不同请求方法可以完成对应的操作
案例:设计一个对课程资源进行操作的RESTful接口
编写controller
package com.kkb.controller;
import com.kkb.pojo.Course;
import com.kkb.service.CourseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
public class RESTCourseController {
@Autowired
CourseService service;
//获取全部课程
@RequestMapping(value = "/course",method = RequestMethod.GET)
public List<Course> getCourseList(){
System.out.println("getCourseList");
return service.selectCourses();
}
//根据id获取某个课程
@RequestMapping(value = "/course/{id}",method = RequestMethod.GET)
public Course getCourse(@PathVariable Integer id){
System.out.println("getCourse");
System.out.println("参数:"+id);
return service.selectByID(id);
}
//添加新的课程
@RequestMapping(value = "/course",method = RequestMethod.POST)
public String addCourse(@RequestBody Course course){
System.out.println("addCourse");
System.out.println("参数:"+course);
service.insertCourse(course);
return "{\"msg\":\"success\"}";
}
//根据id删除课程
@RequestMapping(value = "/course/{id}",method = RequestMethod.DELETE)
public String deleteCourse(@PathVariable Integer id){
System.out.println("deleteCourse");
System.out.println("参数:"+id);
service.deleteCourse(id);
return "{\"msg\":\"success\"}";
}
//根据id更新课程
@RequestMapping(value = "/course",method = RequestMethod.PUT)
public String updateCourse(@RequestBody Course course){
System.out.println("updateCourse");
System.out.println("参数:"+course);
service.updateCourse(course);
return "{\"msg\":\"success\"}";
}
}
@PathVariable是专门用于从url中获取参数的,在RequestMapping中添加{参数名称},作为占位符, 参数名称需要与方法中的参数名称相同,若不同可以为@PathVariable添加value(通常没必要这么做),像下面这样:
@RequestMapping(value = "/course/{cid}",method = RequestMethod.GET)
public Course getCourse(@PathVariable("cid") Integer id){
System.out.println("getCourse");
System.out.println("参数:"+id);
return service.selectByID(id);
}
接口测试推荐使用postman mac可使用paw,
另外在实际开发中我们需要前台传递用户令牌,以验证身份;可以通过拦截器来实现;
补充:
Tomcat 只会解析get和post中的参数,若SpringMVC中使用了PUT或是DELETE,并且使用的是表单提交,那么将无法获取参数,应为Tomcat没有经参数接续出来放到request中,SpringMVC提供了一个过滤器,专门帮助tomcat解析put/delete中的参数并放入request中,配置方法如下:
web.xml:
<!--配置SpringMVC,解析PUT/DELETE的表单数据放入request-->
<filter>
<filter-name>HttpPutFormContentFilter</filter-name>
<filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpPutFormContentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
上述的问题在使用json交互时不会出现,因为SpringMVC是直接从请求体中获取json数据的,不通过request;
啰嗦:如果页面上的表单使用了PUT/或DELETE请求方式,就需要在web.xml中加入上面的过滤器;