本文的框架使用的是SpringBoot1.5
1.前端表單層
代碼中的 @Getter,@Setter,@ToString 是使用的 lombok 用于替代傳統(tǒng)的 setter、getter 、toString方法。
@Getter
@Setter
@ToString
public class UserFormVo {
/**
* 用戶id,修改用戶時(shí)是必填項(xiàng)。增加用戶時(shí)不能傳輸
*/
@NotNull(groups = Update.class, message = "用戶Id不能為空")
@Null(groups = Add.class, message = "不能傳輸用戶Id")
private Long id;
/**
* 用戶名
*/
@NotEmpty(groups = Add.class, message = "用戶名不能為空")
// @Null(groups = Update.class, message = "不能修改用戶名")
@Size(min = 5, max = 20, message = "用戶名個(gè)數(shù)必須為5-20位")
private String name;
/**
* 密碼。新增用戶時(shí)不能為空。修改用戶時(shí)不能修改用戶密碼
*/
@NotNull(groups = Add.class, message = "密碼不能為空")
@Null(groups = Update.class, message = "不能修改用戶密碼")
private String password;
/**
* 用戶狀態(tài)。0禁用,1啟用
*/
@NotNull(group = Add.class, message = "狀態(tài)不能為空")
@Range(min = 0, max = 1, message = "狀態(tài)值不正確")
private Integer status;
/**
* 繼承Default類,可以在不指定@Validated的group時(shí),使用所有默認(rèn)校驗(yàn)方式。
*/
public interface Add extends Default {
}
public interface Update extends Default {
}
}
2.controller層
校驗(yàn)操作是使用 @Validated 來實(shí)現(xiàn)的,通過里面指定的 class 文件來使用不同的注解分組
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 新增用戶
* @Validated 中指定了校驗(yàn)分組,當(dāng)校驗(yàn)注解中有對(duì)應(yīng)的class時(shí),才會(huì)使用對(duì)應(yīng)的校驗(yàn)方式。由于Add.class繼承了Default,所以沒有指定分組的校驗(yàn)方式也會(huì)進(jìn)行調(diào)用
* controller方法可以再添加一個(gè)BindingResult 來接收校驗(yàn)結(jié)果,當(dāng)前后端分離時(shí),因?yàn)槲覀円苯影彦e(cuò)誤返回前端,所以要直接獲取BindingResult中的報(bào)錯(cuò)信息。
* @Return Response是自定義的返回類型。用于同一返回的格式
*/
@PostMapping("/add")
public Response addUser(@Validated(UserFormVo.Add.class) @RequestBody UserFormVo formVo) {
userService.saveUser(formVo);
return Response.success();
}
/**
* 修改用戶
*/
@PostMapping("/modify")
public Response updateUser(@Validated(UserFormVo.Update.class) @RequestBody UserFormVo formVo) {
userService.updateUser(formVo);
return Response.success();
}
}
3.GlobalExceptionHandler
當(dāng)前后端進(jìn)行分離設(shè)計(jì)時(shí),不推薦使用BindingResult來接收校驗(yàn)結(jié)果,controller的方法中不需要添加BindingResult參數(shù)。我改用使用GlobalExceptionHandler來處理錯(cuò)誤信息。
當(dāng)
controller的方法中指定了@Validated,又沒有添加BindingResult參數(shù)時(shí),如果參數(shù)沒有通過校驗(yàn),就會(huì)直接拋出異常,拋出的異常,可以通過使用了@ControllerAdvice的 類進(jìn)行捕獲。
@RestController
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 用于處理參數(shù)校驗(yàn)錯(cuò)誤
* @Validated校驗(yàn)失敗時(shí)會(huì)拋出MethodArgumentNotValidException異常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Response methodArgumentValidExceptionHandler(MethodArgumentNotValidException e) throws Exception {
String code = "200001";
String message = null;
//如果拋出了異常,這個(gè)getErrorCount一定會(huì)>0
if (e.getBindingResult().getErrorCount() > 0) {
//校驗(yàn)會(huì)把所有不通過的選項(xiàng)的錯(cuò)誤信息記錄下來,現(xiàn)在先默認(rèn)給前端提供第一個(gè)錯(cuò)誤信息
message = e.getBindingResult().getAllErrors().get(0).getDefaultMessage();
}
return new Response(code, message);
}
//...其他捕獲全局異常的代碼
}