springboot使用hibernate-validator验证框架的总结

一、引入包

     springboot已经包含有hibernate-validator的包 ,无需引入。

     如为普通maven项目,则引入maven坐标即可。

二、使用

      直接在属性上加上注解即可。

      内置注解详情可参考https://blog.csdn.net/liuchuanhong1/article/details/52042294

三、对象级联校验

     需在要校验的属性上加上@Valid 注解

public class Order {
    @NotBlank(message = "{order.id.notNull}")
    private String orderId;
    @Valid
    private User user;
    
    get ...  set....
}
public class User {
    @NotBlank(message = "{user.id.notNull}")
    private String userId;
    @NotBlank(message = "{user.name.notNull}")
    private String userName;
    @Email
    private String email;
    @BankCard(message = "{bank.card.error}")
    private String bankCard;
    @Pattern(regexp = ValidatorConstant.REGEX_MOBILE, message = "{phone.error}")
    private String phone;
    @IdCard
    private String idCard;
   
    get..   set...
}

四、校验方式

1:直接写工具类调用

public class Test {
    public static void main(String[] args){
     Order order = new Order();
     order.setOrderId("123");
     User user = new User();
     user.setUserId("456");
     user.setUserName("张三");
     user.setEmail("123@11.com");
     order.setUser(user);
     ValidationUtils.validate(order);
    }
}

ValidationUtils工具类代码(其中houseloanexception为自定义异常)

public class ValidationUtils {

    /**
     * 使用hibernate的注解来进行验证
     */
    private static Validator validator = Validation
            .byProvider(HibernateValidator.class).configure().failFast(true).buildValidatorFactory().getValidator();

    /**
     * 功能描述: <br>
     * 〈注解验证参数〉
     *
     * @param obj
     */
    public static <T> void validate(T obj) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
        Iterator<ConstraintViolation<T>> iter = constraintViolations.iterator();
        while (iter.hasNext()) {
            ConstraintViolation<T> error = iter.next();
            System.out.println(error.getPropertyPath().toString());
            throw new HouseloanException("-1",error.getMessage(),error.getPropertyPath().toString());
        }
    }
}

2:在controller里使用   在参数前加上@Valid注解即可。

@RestController
@RequestMapping("/test/")
public class ValidController {
    @PostMapping(value = "valid")
    public Order valid(@RequestBody @Valid Order order){
        return order;
    }
}

五、自定义验证(例如自定义校验银行卡)

  1:自定义注解

  2:定义类实现ConstraintValidator接口并覆写方法,在isValid中实现验证逻辑

  3:需要验证时加上自定义注解即可

@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = BankCard.ValidBankCard.class)
public @interface BankCard {
    String message() default "银行卡格式不正确";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    class ValidBankCard implements ConstraintValidator<BankCard, String> {

        @Override
        public void initialize(BankCard constraintAnnotation) {

        }

        @Override
        public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
            return CheckBankCard.checkBankCard(s);
        }
    }
}
CheckBankCard工具类代码
public class CheckBankCard {
    /*
    校验过程:
    1、从卡号最后一位数字开始,逆向将奇数位(1、3、5等等)相加。
    2、从卡号最后一位数字开始,逆向将偶数位数字,先乘以2(如果乘积为两位数,将个位十位数字相加,即将其减去9),再求和。
    3、将奇数位总和加上偶数位总和,结果应该可以被10整除。
    */

    /**
     * 校验银行卡卡号
     */
    public static boolean checkBankCard(String bankCard) {
        if (bankCard.length() < 15 || bankCard.length() > 19) {
            return false;
        }
        char bit = getBankCardCheckCode(bankCard.substring(0, bankCard.length() - 1));
        if (bit == 'N') {
            return false;
        }
        return bankCard.charAt(bankCard.length() - 1) == bit;
    }

    /**
     * 从不含校验位的银行卡卡号采用 Luhm 校验算法获得校验位
     *
     * @param nonCheckCodeBankCard
     * @return
     */
    private static char getBankCardCheckCode(String nonCheckCodeBankCard) {
        if (nonCheckCodeBankCard == null || nonCheckCodeBankCard.trim().length() == 0
                || !nonCheckCodeBankCard.matches("\\d+")) {
            //如果传的不是数据返回N
            return 'N';
        }
        char[] chs = nonCheckCodeBankCard.trim().toCharArray();
        int luhmSum = 0;
        for (int i = chs.length - 1, j = 0; i >= 0; i--, j++) {
            int k = chs[i] - '0';
            if (j % 2 == 0) {
                k *= 2;
                k = k / 10 + k % 10;
            }
            luhmSum += k;
        }
        return (luhmSum % 10 == 0) ? '0' : (char) ((10 - luhmSum % 10) + '0');
    }
}

六、关于国际化问题

1:在resources目录下新建文件夹i18n   增加配置文件message.properties 

    以key-value方式设置 如:order.id.notNull = 订单id不能为空

2:增加配置文件

@Configuration
public class ValidatorConfiguration {
    public ResourceBundleMessageSource getMessageSource() throws Exception {
        ResourceBundleMessageSource rbms = new ResourceBundleMessageSource();
        rbms.setDefaultEncoding("UTF-8");
        rbms.setBasenames("i18n/message");
        return rbms;
    }

    @Bean
    public Validator getValidator() throws Exception {
        LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
        validator.setValidationMessageSource(getMessageSource());
        return validator;
    }
}

3:使用方式

@NotBlank(message = "{order.id.notNull}")
    private String orderId;

七、参考链接

https://www.cnblogs.com/mr-yang-localhost/p/7812038.html

https://blog.csdn.net/liuchuanhong1/article/details/52042294

https://blog.csdn.net/jin861625788/article/details/73181075

https://blog.csdn.net/liuchuanhong1/article/details/52042294

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值