OVAL實現自定義基於註解的數據驗證

  • 介紹

現在開發項目中數據的安全驗證已是必不可少的一部分,若是隻是讓前段作驗證,並不能保證整個系統的安全。故在介紹一款很是好用的後端驗證數據有效性的框架:oval
oval已經內置支持字段非空,數據長度,數據範圍,正則匹配等驗證,同時還能夠在此框架的基礎上實現自定義的驗證。此次我就介紹一下經常使用的數據是否在數據庫重複的驗證。
依賴:數據庫

<dependency>
            <groupId>net.sf.oval</groupId>
            <artifactId>oval</artifactId>
            <version>1.90</version>
        </dependency>
  • 簡單使用

在此我定義一個User的實體類,其簡單的驗證代碼以下:後端

public class User {
    @NotNull(message = "username can not be null",profiles = "username")
    @Length(min = 8,max = 20,message = "username length error.",profiles = "username")
    @MatchPattern(pattern = "(\\w+)",message = "username have special characters.",profiles = "username")
    private String username;
    private String password;
}

profiles 表示給該字段定義一個標籤,爲對象字段的選擇性驗證而存在。api

  • 自定義驗證註解

上面的列子只是oval自帶的一些驗證,固然這裏也沒有列舉徹底,若是有興趣能夠去查詢其api.基本能夠知足大部分項目需求。但若是須要定義一些特殊的驗證規則這須要咱們本身實現一部分代碼。我這裏舉一個數據庫的字段名是否重複的驗證代碼示例。安全


註解類:app

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Constraint(checkWith = UniqueCheck.class)
public @interface Unique {
    ConstraintTarget[] appliesTo() default {ConstraintTarget.VALUES};

    String errorCode() default "unique error";

    String message() default "field duplicate";

    String[] profiles() default {};

    int severity() default 0;

    String target() default "";

    String when() default "";

    String field();

    String tablename();

    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
    @Constraints
    public @interface List {
        net.sf.oval.constraint.Length[] value();

        String when() default "";
    }

}

數據庫驗重:框架

public class UniqueCheck extends AbstractAnnotationCheck<Unique> {

    private String field;
    private String tablename;
    private String message;

    public boolean isSatisfied(Object validatedObject, Object valueToValidate, OValContext context, Validator validator) throws OValException {

        if (validatedObject == null) return true;
        String value = valueToValidate.toString();
        /**
         * 在此處將表名,字段,值作數據庫操做
         *
         * if exist ,return false
         */

        return true;
    }

    @Override
    protected Map<String, String> createMessageVariables() {
        Map<String, String> re = Validator.getCollectionFactory().createMap(2);
        re.put("message", this.message);
        return re;
    }

    @Override
    public void configure(Unique unique) {
        super.configure(unique);
        field = unique.field();
        tablename = unique.tablename();
        message = unique.message();
    }
}

至此,你只須要在username上面加上以下註解便可支持字段惟一性驗證:ide

@Unique(field="username",tablename="tb_user",profiles="username",message="數據庫已存在")
  • 執行代碼
public static void main(String[] args) {
        User user = new User("zhangsna");
        MyValidator.validator(person, "username");
    }

    static class MyValidator {
        public static <T> void validator(T t, String... profiles) {
            Validator v = new Validator();
            List<ConstraintViolation> message = v.validate(t, profiles);
            for (ConstraintViolation var : message) {
                System.out.println(var.getMessage());
            }
        }
    }
相關文章
相關標籤/搜索