Restful接口详细介绍---完整版

目录

一、restful与传统的接口的区别

 1.传统的接口设计思路:

 2.Restful风格接口设计思路:

 二、Restful 几种请求响应

三、HTTP响应状态码

四、Accept:application/json与Content-Type:application/json

  1.Accept:application/json

  2.Content-Type:application/json

五、实例演示(代码)

六、url 组成部分:  

七、参数路径优缺点:

八、Restful的风格简化


一、restful与传统的接口的区别

首先需要了解的是,restful与传统的接口设计有什么不同,它又有什么好处。

 1.传统的接口设计思路:

   1.请求路径: 见名知意
   2.请求方式: 传统模式会忽略 @RequestMapping
   3.请求参数: 由需求决定
   4.请求响应: 模板路径/由需求决定

 2.Restful风格接口设计思路:

  1.请求路径:由当前接口操作的资源来确定 一个使用资源复数作为路径,比如:/employees
  2.请求方式:  根据接口对资源操作决定 增:post 删:delete  改:put 查 get
  3.请求参数:由需求决定
  4.请求响应:由需求和公司规范决定,一般建议响应数据格式是json格式

  Restful 这是一种设计风格,而不是标准,只是提供了一组设计原则和约束条件,具体的操作还是要结合公司和项目的要求。

 二、Restful 几种请求响应

  get/collection:返回资源对象的列表(数组)
  get/collection/resource 返回单个资源对象
  post/collection/resource 返回新生成的资源对象
  put/collection/resource 返回完整的资源对象
  patch/collection/resource 返回完整的资源对象
  delete/colllection/resource 返回一个空文档

 举个例子来讲,以前传统的请求接口的方式:

    http://www.langfeives.cn.employee/list
    http://www.langfeives.cn.employee/get?id=1
    http://www.langfeives.cn.employee/save?name=xx
    http://www.langfeives.cn.employee/update?id=1&name=xx
    http://www.langfeives.cn.employee/delete?id=1

Restful方式:

      http://www.langfeives.cn.employees  路径都是一样的,只不过采取的方法不一样
      新增:post
      更新:put
      删除:delete
      查询:get

三、HTTP响应状态码

  200 表示请求成功
  400 用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的
  所谓幂等就是 不管进行多少次重复操作,都是实现相同的结果
  401 表示用户没有权限 (令牌、用户名、密码错误)
  403 表明用户得到权限(和401相对),但是访问是被禁止的
  404 NOT FOUND 用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等
  500 服务器发生错误,用户将无法判断发出的请求是否成功
  资源的表现形式

 什么是幂等

   简单来讲就是不管进行多少次重复操作,都是实现相同的结果。

四、Accept:application/json与Content-Type:application/json

    Accept:application/json

      代表客户端希望接受的数据类型 只能是发请求的时候用的。

    Content-Type:application/json

      代表客户端/服务器 携带的数据的类型。
   

五、实例演示(代码)

  实体类:

@Data
 public class Employee{
   private Long id;
   private String name;
   private int age;
 }

  控制层:

	 public class EmployeeController{
	   @RequestMapping("/hello")
	   @ResponseBody
	     public String hello(){
		   return "ok"
		 }
	   }

   获取,新增,更新,删除员工信息

/*     请求路径---确定资源---employees
       请求方法--查询--get
       请求参数 --过滤条件--无
       请求响应---所有员工 List<Employee>----json
 */
@RequestMapping(value ="/employees",method = RequestMethod.GET)
@ResponseBody
 public List<Employee> list(){
   //查询mysql数据库,得到员工列表信息
   //假装查询数据库得到list集合
   List<Employee> list = Arrays.asList(new Employee(1,"zhangsan",18),new Employee(2,"lisi",18))
	     return list;
 } 
新增一个员工:
	/*请求路径---确定资源---employees
	  请求方法--添加--post
	  请求参数 --员工相关属性--name,age
	  请求响应--- 新增员工对象--Employee----json
	 */
@RequestMapping(value ="/employees",method = RequestMethod.POST)
@ResponseBody
public Employee save(Employee employee){
  //查询mysql数据库,得到员工列表信息
  //假装添加数据成功,返回自动增长的id值
  employee.setId(1);
  return employee;
} 
更新一个员工
/*请求路径---确定资源---employees
  请求方法--更新--put
  请求参数 --员工相关属性--id,name,age
  请求响应--- 新增员工对象--Employee----json
*/
@RequestMapping(value ="/employees",method = RequestMethod.PUT)
@ResponseBody
public Employee update(Employee employee){
  employee.setName(employee.getName()+"_update");
  return employee;
} 
删除一个员工
/*请求路径---确定资源---employees
  请求方法--删除--delete
  请求参数 --员工相关属性--id
  请求响应---删除之后的状态--JsonResult----json
  JsonResult: 统一的响应返回值;
*/
@RequestMapping(value ="/employees",method = RequestMethod.DELETE)
@ResponseBody
public JsonResult update(Employee employee){
  //假装删除成功
  return JsonResult.success;
} 

   JsonResult类:

@Setter
@Getter
	 public class JsonResult{
	   private int code;   //请求操作完之后返回的状态码,操作成功200,操作失败500,没有登录403
	   private String msg;  //请求操作之后返回信息
	   private Object data;  //请求的响应数据
	  public JsonResult(int code,String msg,Object data){
	    this.code = code;
		this.msg = msg;
		this.data = data;
	  }
	  public static JsonResult error(String msg){
	    return new JsonResult(500,msg,null);
	  }
	  public static JsonResult error(String msg,Object data){
	    return new JsonResult(500,msg,data);
	  } 
	   public static JsonResult success(String msg){
	    return new JsonResult(500,"操作成功",null);
	  }
	  public static JsonResult success(String msg,Object data){
	    return new JsonResult(500,"操作成功",data);
	  } 
	 }
  

  如果查询某个员工的信息,那么按照上述思路应该是:

	/*请求路径---确定资源---employees
	  请求方法--查询--get
	  请求参数 --id
	  请求响应---某一个员工--Employee----json
	 */
	   @RequestMapping(value ="/employees",method = RequestMethod.GET)
	   @ResponseBody
	   public Employee detail(Long id){
		 return new Employee(id,"zhangsan",18);
	   } 
	 }

  但是这样的话,无论是映射路径上还是请求方法上都和查询所有员工的接口完全相同,springmvc会认为是同一个接口,从而报错,既然不能同时存在,那应该如何解决这一问题呢?

  有如下两种方法;

  1.使用多级路径方法 比如:/employees/details

  2.使用参数路径方式 比如:/employees/{id}  将请求参数作为路径的一部分 进行url区分

  参数路径:/employees/{id} ,其中{id} 参数占位符
  客户端访问: http://localhost:80/employees/1 1就是id参数值

注意点

  接口要获取参数路径中参数必须使用@PathVarible,目的是让springmvc 是参数解析器从路径中解析出参数并进行复制

  如果参数路径中的占位符名称与请求映射方法形式参数名称不一致时,必须明确指定映射

如:  /employees/{eid} -------->@PathVarible("eid") long id

  如果参数路径中包含很多个参数时,可以按下面这种写法:

@RequestMapping(value = "/employees/{id}{name}/{age}",method = RequestMethod.GET)
@RequsetBody
public Employee info(@PathVarible Long id,@PathVarible String name,@PathVarible int age){
  return new Employee (id,name,age)
}

  但是采用这种写法,就这么看着就已经很麻烦了,如果是十几个参数难道要一个一个解析么,答案肯定不是这样的,我们可以直接封装在对象当中,这样也是能够取到的:

@RequestMapping(value = "/employees/{id}{name}/{age}",method = RequestMethod.GET)
@RequsetBody
public Employee info(Employee employee){
  return employee;
}

 接下来对比一下这些的url有什么不同:

对应的url: http://localhost:80/employees?id=1&name=zhangsan
@RequestMapping(value = "/employees",method = RequestMethod.GET) 
@RequsetBody
public Employee detail(Long id,String name){
	return new Employee(id,name,18);
}

对应的url: http://localhost:80/employees/1?name=zhangsan
@RequestMapping(value = "/employees{id}",method = RequestMethod.GET) 
@RequsetBody
public Employee detail(@PathVarible Long id,String name){
	return new Employee(id,name,18);
}

对应的url: http://localhost:80/employees/1/zhangsan
@RequestMapping(value = "/employees/{id}/{name}",method = RequestMethod.GET) 
@RequsetBody
public Employee detail(@PathVarible Long id,@PathVarible String name){
	return new Employee(id,name,18);
}

六、url 组成部分:  

  协议://ip:端口/路径?参数1=参数1值&参数2=参数2值...

  例如:http://localhost:80/employees?id=1&name=zhangsan

七、参数路径优缺点:

 优点:可以在一定程度上隐藏参数

 缺点:   如果参数较多,url路径就很长,不优雅

 在真实的开发中一般是采用两者混用。

如何在页面上调用接口(js)

<script>
	     $(function(){
		   $("btn1").click(function(){
		     //发起异步请求---查单个
			 $.get("/employees/1",function(data){
			    console.log(data);
			 })
		   })
		    $("btn2").click(function(){
		     //发起异步请求---查多个
			 $.get("/employees",function(data){
			    console.log(data);
			 })
		   })
		   $("btn2").click(function(){
		     //发起异步请求---添加
			 $.post("/employees",{name:"zhangsan",age:18},function(data){
			    console.log(data);
			 })
		   })
		   $("btn2").click(function(){
		     //发起异步请求---更新
			 $.ajax({
			   url:"/employees",
			   type:"PUT",
			   data:{id:1,name:"zhangsan",age:18},
			   success:function(data){
			     console.log(data);
			   }
			 })
		   })
		 })
</script>

注意点:

   传统的SpringMvc默认不支持put请求,需要配置处理put或者patch请求方式的过滤器。

<filter>
  <filter-name>httpPutFormContentFilter</filter-name>
  <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class>
</filter>
<filter>
  <filter-name>httpPutFormContentFilter</filter-name>
  <servlet-name>springMVC</servlet-name>
</filter>

八、Restful的风格简化

  实际上按照上面的写法会有很多重复的内容,因此还有更简化的方法,下面进行对比介绍

正常:

@Controller
public class EmplyeeController{
    @RequestMapping(value ="/employees",method = RequestMethod.GET)
    @ResponseBody
     public List<Employee> list(){
       List<Employee> list = Arrays.asList(new Employee(1,"zhangsan",18),new                 Employee(2,"lisi",18))
	   return list;
 } 

    @RequestMapping(value ="/employees",method = RequestMethod.POST)
    @ResponseBody
    public Employee save(Employee employee){
      employee.setId(1);
      return employee;
} 

    @RequestMapping(value ="/employees",method = RequestMethod.PUT)
    @ResponseBody
    public Employee update(Employee employee){
      employee.setName(employee.getName()+"_update");
      return employee;
    } 
    @RequestMapping(value ="/employees",method = RequestMethod.DELETE)
    @ResponseBody
    public JsonResult update(Employee employee){
      return JsonResult.success;
    } 

}

简化后:

@RestController  //等价于: @RequstBody+@Controller
@RequestMapping("employees")
public class EmplyeeController{
     @GetMapping
     public List<Employee> list(){
       List<Employee> list = Arrays.asList(new Employee(1,"zhangsan",18),new                 Employee(2,"lisi",18))
	   return list;
     } 
     @GetMapping("/{id}")
     public List<Employee> detail(@PathVarible Long id){
       List<Employee> list = Arrays.asList(new Employee(1,"zhangsan",18),new                 Employee(2,"lisi",18))
	   return list;
     }
     @PostMapping
     public Employee save(Employee employee){
       employee.setId(1);
       return employee;
     } 

    @PutMapping
    public Employee update(Employee employee){
      employee.setName(employee.getName()+"_update");
      return employee;
    } 
    @DeleteMapping
    public JsonResult update(Employee employee){
      return JsonResult.success;
    } 

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿土不土

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值