1 概述
本篇文章以Spring Boot为基础,从以下三个方向讲述了如何设计一个优秀的后端接口体系:
- 参数校验:涉及Hibernate Validator的各种注解,快速失败模式,分组,组序列以及自定义注解/Validator
- 异常处理:涉及ControllerAdvice/@RestControllerAdvice以及@ExceptionHandler
- 数据响应:涉及如何设计一个响应体以及如何包装响应体
有了一个优秀的后端接口体系,不仅有了规范,同时扩展新的接口也很容易,本文演示了如何从零一步步构建一个优秀的后端接口体系。
2 新建工程
打开熟悉的IDEA,选择依赖:
首先创建如下文件:
TestController.java:
@RestController
@RequestMapping("/")
@CrossOrigin(value = "http://localhost:3000")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TestController {
private final TestService service;
@PostMapping("test")
public String test(@RequestBody User user)
{
return service.test(user);
}
使用了@RequiredArgsConstructor代替@Autowired,由于笔者使用Postwoman测试,因此需要加上跨域注解@CrossOrigin,默认3000端口(Postwoman端口)。
TestService.java:
@Service
public class TestService {
public String test(User user)
{
if(StringUtils.isEmpty(user.getEmail()))
return "邮箱不能为空";
if(StringUtils.isEmpty(user.getPassword()))
return "密码不能为空";
if(StringUtils.isEmpty(user.getPhone()))
return "电话不能为空";
// 持久化操作
return "success";
}
}
业务层首先进行了参数校验,这里省略了持久化操作。
User.java:
@Data
public class User {
private String phone;
private String password;
private String email;
}
3 参数校验
首先来看一下参数校验,上面的例子中在业务层完成参数校验,这是没有问题的,但是,还没进行业务操作就需要进行这么多的校验显然这不是很好,更好的做法是,使用Hibernate Validator。
3.1 Hibernate Validator
3.1.1 介绍
JSR是Java Specification Requests的缩写,意思是Java规范提案,是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。JSR-303是Java EE6中的一项子规范,叫作Bean Validation,Hibernate Validator是Bean Validator的参考实现,除了实现所有JSR-303规范中的内置constraint实现,还有附加的constraint,详细如下:
- @Null:被注解元素必须为null(为了节省篇幅下面用“元素”代表“被注解元素必须为”)
- @NotNull:元素不为null
- @AssertTrue:元素为true
- @AssertFalse:元素为false
- @Min(value):元素大于或等于指定值
- @Max(value):元素小于或等于指定值
- @DecimalMin(value):元素大于指定值
- @DecimalMax(value):元素小于指定值
- @Size(max,min):元素大小在给定范围内
- @Digits(integer,fraction):元素字符串中的整数位数规定最大integer位,小数位数规定最大fraction位
- @Past:元素是一个过去日期
- @Future:元素是将来日期
- @Pattern:元素需要符合正则表达式
其中Hibernate Validator附加的constraint如下:
- @Eamil:元素为邮箱
- @Length:字符串大小在指定范围内
- @NotEmpty:字符串必须非空(目前最新的6.1.5版本已弃用,建议使用标准的@NotEmpty)
- @Range:数字在指定范围内
而在Spring中,对Hibernate Validation进行了二次封装,添加了自动校验,并且校验信息封装进了特定的BindingResult中。下面看看如何使用。
3.1.2 使用
在各个字段加上@NotEmpty,并且邮箱加上@Email,电话加上11位限制,并且在各个注解加上message,表示对应的提示信息:
@Data
public class User {
@NotEmpty(message = "电话不能为空")
@Length(min = 11,max = 11,message = "电话号码必须11位")
private String phone;
@NotEmpty(message = "密码不能为空")
@Length(min = 6,max = 20,message = "密码必须为6-20位")
private String password;
@NotEmpty(message = "邮箱不能为空")
@Email(message = "邮箱格式不正确")
private String email;
}
对于String来说有时候会使用@NotNull或@NotBlank,它们的区别如下:
- @NotEmpty:不能为null并且长度必须大于0,除了String外,对于Collection/Map/数组也适用
- @NotBlank:只用于String,不能为null,并且调用trim()后,长度必须大于0,也就是必须有除空格外的实际字符
- @NotNull:不能为null
接着把业务层的参数校验操作删除,并把控制层修改如下:
@PostMapping("test")
public String test(@RequestBody @Valid User user, BindingResult bindingResult)
{
if(bindingResult.hasErrors())
{