一、引入包
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