请君入坑:RESTFul设计风格(一)
①
有一次面试,面试官问:“什么是REST风格?”
自己也是刚接触这一个概念,并没有系统化的去学习,就含含糊糊地回答:“前台用GET请求,后台也用GET接收;前台用POST请求,后台也用POST接收……”
还没等我说完,就被面试官就打断:“前台用GET请求,后台用POST接收,能接收到吗?”
“额,不能。”
“你们项目里用过吗?”
“用过的。”
“有接口文档吗?”
“有”
“接口是怎么命名的?”
当时,傻了眼,不知道该怎么描述,是动词名词相结合吗,驼峰式的命名法?支支吾吾了半天……更不知道面试官葫芦里装的什么药,这样问的目的是什么,心里的几只小兔子一直蹦呀跳呀,不敢轻易回答,忐忑。
就这样,在这场面试中,灰不溜秋的败下阵来。
回到家中,立刻翻书查资料,终于明白了面试官为何这样问。
②
请看这段代码:
@RestController
public class TestController {
@RequestMapping("/test")
public Object test(){
return "test";
}
}
如果仅仅在Controller类上加上@RestController,有了Rest字样,就认为已经实现了REST风格,那也是大错特错了,这只是RESTFul风格的冰山一角哟。当然,自己也曾经这么傻傻地认为。
先来说说这个@RestController的作用吧,
@RestController = @Controller + @ResponseBody,没错上面的代码等同于下面的代码:
@Controller
public class TestController {
@ResponseBody
@RequestMapping("/test")
public Object test(){
return "test";
}
}
为什么等同呢,一看运行结果,二看源码,请看@ResponseBody的源码,源码最有说服力:
图-1③
那到底什么是RESTFul风格呢?看官方解释,REST是英文Representational State Transfer的简称,可以翻译为表现层状态转换。它是一种软件架构风格,在两千年的时候,这种思想提出了,如今发展也快十个年头了,具体的可以自己网上搜,个人推荐阮一峰的网络日志:http://www.ruanyifeng.com/blog/2011/09/restful.html
下面上代码,进入使用阶段,下面的这四种是比较常用的,还有PATCH(UPDATE)、HEAD、OPTIONS这三种不常用,就不列举了。
/**
* RESTFul风格代码示范
* @author ME
*
*/
@RequestMapping("/user")
@RestController
public class UserController {
/**
* 新增(CREATE)
* @param user
* @return
*/
@RequestMapping(value="/save",method= RequestMethod.POST)
public Object save(User user) {
System.out.println("数据库持久层操作");
returnuser.getUserMobile();
}
/**
* 修改(UPDATE)
* @param userUid
* @param user
* @return
*/
@RequestMapping(value="/{userUid}",method= RequestMethod.PUT)
public Object update(@PathVariableInteger userUid,User user) {
System.out.println("数据库持久层操作");
returnuserUid;
}
/**
* 删除数据(DELETE)
* @param userUid
* @return
*/
@RequestMapping(value="/{userUid}",method= RequestMethod.DELETE)
public Object delete(@PathVariableString userUid) {
System.out.println("数据库持久层操作");
return userUid;
}
/**
* 查询单条数据(VISIT)
* @param userUid
* @return
*/
@RequestMapping(value="/{userUid}",method= RequestMethod.GET)
public Object info(@PathVariableString userUid) {
System.out.println("数据库查询操作");
returnuserUid;
}
}
REST设计风格,简单地说就是资源定位,每一个资源对应一个网址,既然是资源,那就不应该有非名词存在。这也是上面面试官问接口命名规范的最终原因(看来不管自己怎么回答都是错,不回答也是错),如果接口的命名规范不按照这个来,那也称不上遵循什么RESTFul设计规范了。
④
代码写好了,还要测试吧,GET可以直接在浏览器进行测试,POST、PUT、DELETE这三种方法可以使用模拟器测试,在这里使用API POST工具。
本人使用的开发环境是Spring Boot 2.1.4.RELEASE版本的,对应的Spring Cloud版本是Greenwich.SR1。
GET方法测试结果如下,这个方法也可以直接在浏览器上进行测试。
图-2POST方法测试结果如下,这个就得用模拟器进行模拟了。
图-3在做PUT测试时,后台总是报错,报错信息如下:
图-4API POST模拟工具这边报500的错误,如下图:
图-5org.apache.tomcat.util.http.fileupload.FileUploadException,不明白为何报上传文件的错误,难道还要限制上传文件的大小不成,这里并没有涉及任何上传文件呀,只是文本类型,在网上查了一下资料,加了一个header就可以了。
图-6DELETE测试报的错误和PUT一样,在DELETE中,只有请求头,没有body的,还需要设置什么呢?
图-7继续踩坑,在header中加了一个Content-Type,并设置为application/x-www-form-urlencoded;好吧,这下OK了。
图-8还有一个注意点,附在URI后面的参数,在接收时,是必须加@PathVariable注解进行修饰的,否则在后台是获取不到参数的。
图-9RESTFul设计风格的简单使用,就告一个段落了,入门级的使用还是比较简单的,只是在使用的过程中,会遇到很多坑,需要一个一个踩,你get到了吗?
可是有人会说,做这个测试可以不用API POST工具,那用什么呢,请看下集继续。
有一个疑问还没有想明白,那就是Content-Type为何要换成application/x-www-form-urlencoded; 难道是因为API POST模拟了浏览器?
application/x-www-urlencoded是浏览器默认的编码格式
multipart/form-data是form表单提交
application/json是ajax请求