在以往Bean Validation通常會在service的function寫上好長一段判斷如下
//合法性校驗
if (StringUtils.isBlank(dto.getName())) {
throw new XueChengPlusException("課程名稱為空");
}
if (StringUtils.isBlank(dto.getMt())) {
throw new XueChengPlusException("課程分類為空");
}
if (StringUtils.isBlank(dto.getSt())) {
throw new XueChengPlusException("課程分類為空");
}
if (StringUtils.isBlank(dto.getGrade())) {
throw new XueChengPlusException("課程等級為空");
}
然而當欄位多起來的時候,code看起來就會變得冗長
且如果不同的function都要來一段這個,這些也有許多重複的程式碼其實也有改進空間
而在JavaEE6規範中就定義了參數校驗的規範
它就是JSR-303,它定義了Bean Validation,即對bean屬性進行校驗
SpringBoot提供了JSR-303的支持,它就是spring-boot-starter-validation,它的底層使用Hibernate Validator,Hibernate Validator是Bean Validation 的參考實現。
所以,我們準備在Controller層使用spring-boot-starter-validation完成對請求參數的基本合法性進行校驗。
以下的組合是可以讓不同的controller使用不同組的校驗文字
我們在專案中的exception包定出GlobalExceptionHandler和ValidationGroups
GlobalExceptionHandler
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(XueChengPlusException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse customException(XueChengPlusException e) {
log.error("【系統異常】{}",e.getErrMessage(),e);
return new RestErrorResponse(e.getErrMessage());
}
@ResponseBody
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse exception(Exception e) {
log.error("【系統異常】{}",e.getMessage(),e);
return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
}
@ResponseBody
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public RestErrorResponse methodArgumentNotValidException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
List msgList = new ArrayList<>();
bindingResult.getFieldErrors().stream().forEach(item->{
msgList.add(item.getDefaultMessage());
});
String msg = StringUtils.join(msgList, ",");
log.error("【系統異常】{}",msg);
return new RestErrorResponse(msg);
}
}
ValidationGroups
public class ValidationGroups {
public interface Insert{};
public interface Update{};
public interface Delete{};
}
目前將ValidationGroups分成新增, 更新, 刪除三個類別
在bean上設置的檢核訊息如下
@Data
@ApiModel(value="AddCourseDto", description="新增課程基本信息")
public class AddCourseDto {
@NotEmpty(groups = {ValidationGroups.Insert.class},message = "新增課程名稱不能為空")
@NotEmpty(groups = {ValidationGroups.Update.class},message = "修改課程名稱不能為空")
@ApiModelProperty(value = "課程名稱", required = true)
private String name;
...
}
然後使用上, 我們在controller就可以這樣寫, 比方說我們此類為新增 就使用Insert @Validated({ValidationGroups.Insert.class})
@ApiOperation("新增課程基礎信息")
@PostMapping("/course")
public CourseBaseInfoDto createCourseBase(@RequestBody @Validated({ValidationGroups.Insert.class}) AddCourseDto addCourseDto){
//獲取到用戶所屬機構id
Long companyId = 1232141425L;
return courseBaseInfoService.createCourseBase(companyId,addCourseDto);
}
沒有留言:
張貼留言