推荐阅读:
Docker实战PDF丨由浅入深,用基本原理和具体案例让你掌握容器化
深入浅出Kafka,什么样的Kafka学习文档让阿里架构师都争相收藏
服务器后台设计API接口时,目前最流行的风格(原则/标准/规范)就是RESTful,往往简称为REST。
其中 REST=REpresentational State Transfer
REST直译:表现层状态转移
REST核心含义:无状态的资源 资源的变化(CURD)都是通过操作去实现的 资源可以用 URI 表示 用不同的URI和方法,表示对资源的不同操作
简单的说,就是使用同一个URI,就能实现增删改查的请求。而区别增删改查则需要以下典型的Rest方法:
- GET:获取资源
- POST:新建资源
- PUT:更新资源
- DELETE:删除资源
1.Spring中对Restful的支持
Spring对Restful有很好的支持,提供了以下注解分别对应上述的方法。
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
2.使用Restful实现增删改查
那么我们走一遍增删改查。通过以下例子可以看出,不管增删改查,URI都是http://localhost:8081/test/companies/。这样对你的程序设计,维护,文档设计,维护都很有帮助。
2.1 @GetMapping 取得数据
前端请求url例子
http://localhost:8081/test/companies/任意公司ID
后端接收代码。这里要讲解的就是,@GetMapping中的{companyId}代表具体的公司id,配合@PathVariable注解,就能够将URL中的字符串提取成参数变量。
@GetMapping(value="/companies/{companyId}")public ResponseDto getCompany(@PathVariable("companyId") int companyId) {return service.getCompany(companyId);}
2.2 @PostMapping 插入数据。取到Json的值,做数据校验
前端请求url例子
http://localhost:8081/test/companies/
如果用postman测试,你需要包含一段json,作为你要插入的数据。
![27b57a6351205dd35a33bdcbcb295ca6.png](https://i-blog.csdnimg.cn/blog_migrate/2d9fb4cd56c16754ae98c41200e907f3.jpeg)
后端代码。因为你的接收数据在body中,所以实体类前必须添加@RequestBody注解。当然了,你也可以进行数据校验,并把结果放入BindingResult。
@PostMapping(value="/companies")public ResponseDto regitsCompany(@Valid @RequestBody MCompany dto, BindingResult result) { return service.registCompany(dto);}
2.3 @PutMapping 更新数据。同时取到URL的值跟json的值
前端URL例子。跟2.2中的post一样,body中传递json。这里就不截图了。
http://localhost:8081/test/companies/任意公司ID
后端代码。这里又有一个变通,就是既需要使用@PathVariable,又要使用@RequestBody,才能把url中的值跟json的值同时取到。
@PutMapping(value="/companies/{companyId}")@Transactionalpublic ResponseDto updateCompany(@PathVariable("companyId") int companyId, @Valid @RequestBody MCompany dto, BindingResult result) { dto.setCompanyId(companyId); return service.updateCompany(dto);}
2.4 @DeleteMapping 删除数据
前端URL例子
http://localhost:8081/test//companies/任意公司ID
后端代码。这个就没什么好讲的了。
@Transactional@DeleteMapping("/companies/{companyId}")public ResponseDto deleteCompany(@PathVariable("companyId") int companyId) { return service.deleteCompany(companyId);}
3. 返回数据的格式跟风格
3.1 请求处理正常
上述controller中ResponseDto的代码是这样的。
@Data@Componentpublic class ResponseDto {// 状态码private String code;// 状态信息private String msg;// 响应数据private Object data;}
这是Restful返回的比较标准的格式。
![6a27e96ad598f1b2a376cf36b894d758.png](https://i-blog.csdnimg.cn/blog_migrate/4f092c9684dd7b3ca96d76c7f7a169f2.jpeg)
3.2 请求处理异常
发生异常的话,有可能是数据校验出错,那样压根不进入controller方法体。也有可能在其他地方出错,比如进入方法体后的片段中出错,我们应该统一在ExceptionHander中处理。
像下面这样,我们返回ResponseEntity,并与HttpStatus关联,当然可以是400,404,500。ResponseDto中你可以放同样的code,也可以是你自己自定义的错误码。这里我们为了方便就设置成同样的。
![c04fd3b5699bc1e22d765b5eaa77d09e.png](https://i-blog.csdnimg.cn/blog_migrate/fd509828af706ee146e3e1b513e461ae.jpeg)
比如请求中的邮件地址非法,就会进入ValidationException的分支,出现上述图片的错误。
@RestControllerAdvicepublic class GlobalExceptionController { Logger logger = LogManager.getLogger(GlobalExceptionController.class); @Autowired ResponseDto res; private ResponseEntity buildResponse(Exception e, HttpStatus status) { logger.error(e.getMessage()); res.setCode(String.valueOf(status.value())); res.setMsg(e.getMessage()); res.setData(""); return new ResponseEntity(res, status); } // 数据校验错误 @ExceptionHandler(ValidationException.class) public ResponseEntity handleError(ValidationException e) { return buildResponse(e, HttpStatus.BAD_REQUEST); } // 文件IO错误 @ExceptionHandler(FileException.class) public Object handleError(FileException e) { return buildResponse(e, HttpStatus.INTERNAL_SERVER_ERROR); } // 业务逻辑错误 @ExceptionHandler(SiLEDBusinessException.class) public Object handleError(SiLEDBusinessException e) { return buildResponse(e, HttpStatus.BAD_REQUEST); } // 其他错误 @ExceptionHandler(Exception.class) public Object handleError(Exception e) { return buildResponse(e, HttpStatus.INTERNAL_SERVER_ERROR); }}
4. Restful的其他事项
4.1正则表达式
如果你想精准的匹配URL,可以使用正则表达式。
@RequestMapping(value = "/{name:([a-z][0-9a-z-]{3,31}}/mytest",method = {RequestMethod.GET})public void test(@PathVariable String name){ }
4.2 put跟patch的区别
上面没有讲到一种patch请求,该请求也是更新请求,但是是局部更新。什么是局部更新?加入有个user类,你更新他的所有属性,就用put。只更新username可以用put,但是显得很大题小作,因为put是全面替换。这时可以使用patch,仅更新username。
4.3 Options请求跟web.xml配置
如果涉及到跨域,在请求Restful之前,浏览器会先发送一个Options请求给后台,询问该接口/端点支持哪些方法。所以需要配置该许可。
appServletorg.springframework.web.servlet.DispatcherServletdispatchOptionsRequesttruecontextConfigLocation/WEB-INF/spring/appServlet/servlet-context.xml1
原文:https://www.tuicool.com/articles/iAbEra3