背景
笔者目前所在团队的代码年代已久,早年规范缺失导致现在维护成本激增,举一个深恶痛疾的例子就是方法参数使用Map“一撸到底“,说多了都是泪,我常常在团队内自嘲“咱硬是把java写成了JavaScript、php”,代码灵活的让人怀疑人生,你根本不知道方法需要什么、返回什么,新人来了想快速上手不可能的,老老实实debug吧,另一方面,以往的校验大多数都是放在前端做的,后端几乎没有校验,所幸业务量没上来,没有引起不速之客的造访,要不程序员早被拉去祭天多少回了。
恰逢接到一个任务在团队内推广参数校验,希望能带来一些业内的最佳实践,开始我内心是拒绝的:“这么成熟的东西还需要普及什么呢,网上一搜一大篇”,罢了罢了,拿人钱财,从开始的抵触到后来的坦然,还是有不少收获,待我娓娓道来。
业内实践
1.简单粗暴的if else
if(a == null){
return Result.failure(400,"a不能为空);
}
if(StringUtil.isEmpty(b)){
return Result.failure(400,"b不能为空);
}
通俗易懂的校验方式,不使用框架,代码重复度会比较高,参数较少的简单场景可以这么用。
2.JSR规范+hibernate validator框架【成熟体系】
JSR提供了一套Bean校验规范的API,维护在包javax.validation.constraints下。该规范使用属性或者方法参数或者类上的一套简洁易用的注解来做参数校验。开发者在开发过程中,仅需在需要校验的地方加上形如@NotNull, @NotEmpty , @Email的注解,就可以将参数校验的重任委托给一些第三方校验框架来处理。
接入validation api及hibernate validator后,做校验就很easy了
@Entity
public class Blog {
public Blog() {
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@NotNull
@Size(min = 2, message = "Blog Title must have at least 2 characters")
private String blogTitle;
@NotBlank(message = "Blog Editor cannot be blank")
private String blogEditor;
@Email(message = "Email should be valid")
private String blogEmail;
// Getters and Setters
}
@RestController
@RequestMapping("api/v1")
public class BlogController {
@PostMapping("/blog")
public Blog saveBlog(@Valid @RequestBody Blog savedBlog,BindingResult result) {
if(result.hasErrors()){
// 获取异常信息对象
List<ObjectError> errors = result.getAllErrors();
// 将异常信息输出
for (ObjectError error : errors) {
//执行自己的逻辑
}
}
}
场景复杂,参数多,这时我们就需要借助框架来助力,减少重复工作量,框架久经验证,bug相对来讲较少。
想深入了解的,可以参考官方文档
Getting Started | Validating Form Input (spring.io)
3.json schema+json schema validator【新宠】
json schema 是用于验证 JSON 数据结构的强大工具,适用于表单灵活变动、controller层没有定义对象数据绑定情况下(我们现在的场景就是大量使用Map接收前端数据,没法使用JSR规范+hibernate validator框架)
@RestController
@RequestMapping("api/v1")