1. 程式人生 > 其它 >【物聯網天線選擇攻略】2.4GHz 頻段增益天線模組裝置選擇

【物聯網天線選擇攻略】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 ()中校驗從前端傳遞的值。