2023年12月10日 星期日

JSR-303 Bean Validation

 在以往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);
    }

沒有留言:

張貼留言

創業想法1

現在有駐點工作的公司 今天突然想到 那為什麼沒有遠端駐點公司 就是接國外的職位 幫他找台灣人 在公司上遠端工作的職缺 有可能是因為時差 所以這種公司上班時間不同, 並不好管理 但是感覺理論上是存在需求 就是台灣人想找遠端職缺, 但是可能語言上或技能上還差點火候 公司提供培訓, 並...