【物聯網天線選擇攻略】2.4GHz 頻段增益天線模組裝置選擇
用於表單提交資料的校驗,雖然前端可以做校驗,但是為了安全起見,建議後端再做一次校驗。
使用
entity的欄位上添加註解對應的註解即可實現對該屬性的驗證,比如:
@NotNull
private Integer phone;
當然除了@NotNull
還有許多其他註解,就不一一演示了。
在Controller中方法的引數上標註@Valid
,兩者需搭配使用才生效。
BindingResult
封裝了所有的校驗失敗資訊,但是BindingResult
必須緊跟在@Valid
後面,比如:@Valid @RequestBody BrandEntity brand BindingResult result
if (result.hasErrors()) { Map<String, String> map = new HashMap<>(); result.getFieldErrors().forEach((item) -> { String message = item.getDefaultMessage(); String field = item.getField(); map.put(field, message); }); return R.error(400, "提交的資料不合法").put("data", map); } else { brandService.save(brand); return R.ok(); }
統一異常處理&&返回
定義一個統一異常處理,從而不用在每個Controller中都定義BindingResult
用列舉定義統一的返回結果:
public enum BizCodeEnume { UNKNOW_EXCEPTION(10000,"系統未知異常"), VAILD_EXCEPTION(10001,"引數格式校驗失敗"); private int code; private String msg; BizCodeEnume(int code,String msg){ this.code = code; this.msg = msg; } public int getCode() { return code; } public String getMsg() { return msg; } }
自定義異常處理:
@RestControllerAdvice
@Slf4j
public class UnifiedExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public R error(MethodArgumentNotValidException e) {
BindingResult result = e.getBindingResult();
Map<String, String> map = new HashMap<>();
result.getFieldErrors().forEach((item) -> {
String message = item.getDefaultMessage();
String field = item.getField();
map.put(field, message);
});
return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(), BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data", map);
}
@ExceptionHandler(Throwable.class)
public R handleException(Throwable e){
return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(), BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",e.getMessage());
}
}
分組校驗
每個註解中都有groups
欄位,要想使用分組需定義介面,介面中不需要寫任何程式碼,僅作為標識。
在欄位上新增 @NotNull(message = "提示資訊", groups = {AddGroup.class})
,Controller中將@Valid
修改為 @Validated(AddGroup.class)
,該註解是spring
提供的,這些註解的意思就是:該欄位不能為空,並且分組為AddGroup
並設定Controller要校驗的分組,添加了分組後那些未新增該分組的欄位在該Controller中就不會校驗了
自定義校驗註解
參考javax.validation.constraints
包下定義的註解,我們可以自定義註解:
@Documented
@Constraint(validatedBy = {CustomValidator.class})
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
public @interface CustomCheck {
String message() default "只能提交0或1";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] vals() default {};
}
在entity
新增上自己寫的註解:
@CustomCheck(vals = {0, 1})
private Integer showStatus;
但是,什麼時候校驗成功呢?vals = {0, 1}定義了校驗成功的資料,我們還需要寫一個校驗器來完成最終校驗:
public class CustomValidator implements ConstraintValidator<CustomCheck, Integer> {
private Set<Integer> set = new HashSet<>();
@Override
public void initialize(CustomCheck constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
return set.contains(value);
}
}
constraintAnnotation.vals()
封裝了從前端傳過來的資料,最後在isValid ()
中校驗從前端傳遞的值。