android上的java bean 校验-Hibernate Validator移植

8,490 阅读2分钟

Bean Validator on Android

适用场景

拿到后台数据后,如何更高效地校验数据有效性,而不是在代码里写一堆if else判断?

image-20200901150246361

要移植到Android,需要考虑java8兼容性问题,性能(方法耗时),以及对apk大小的影响,默认使用的是Apache BVal 1.1.2

使用

初始化

BeanValidator.init(this);

使用

image-20200529144724999

提供了中英文的默认文案:

image-20200529144800253

image-20200529144823249

自定义配置文案:

image-20200529144851858

校验:

String errorMsg = BeanValidator.validate(bean);
//返回的errorMsg为空就说明校验通过
if(!TextUtils.isEmpty(errorMsg)){
    Toast.makeText(this,errorMsg,Toast.LENGTH_LONG).show();
}else {
    //拿到合格的bean
}

retrofit使用

Retrofit retrofit = new Retrofit.Builder()
        .addConverterFactory(GsonConverterFactoryWithBeanValidator.create())

image-20200529145402034

返回的msg的格式:

可以直接显示给用户

image-20200529145018717

gradle使用:

implementation 'com.github.hss01248.AndroidBeanValidator:apacheval:1.0.2'//默认使用Apache BVal
  //如果使用hibernate:
  implementation 'com.github.hss01248.AndroidBeanValidator:hibernateval:1.0.2'
implementation 'com.github.hss01248.AndroidBeanValidator:gsonconvertervalidator:1.0.2'

注意

不能混淆相关的string资源.

如果使用微信的资源混淆工具andresgruard,可以将验证翻译放到同一个xml文件中,然后添加忽略.

比如:

andResGuard {
    use7zip = false
    useSign = true
    // it will keep the origin path of your resources when it's true
    keepRoot = false
    whiteList = [
            "R.string.validator_msg",
            ....

apk

大小相差不大

image-20200901144216387

方法耗时

Apache Bval

第一次初始化validate factory比较耗时,后续很快

第一次几百ms级别,后续是ms级别

image-20200901143534698

hibernate validator 稍微差一点点

image-20210112170225457

ps.hibernate Validator的兼容

hibernate的校验模式

上面例子中一次性返回了所有验证不通过的集合,通常按顺序验证到第一个字段不符合验证要求时,就可以直接拒绝请求了。Hibernate Validator有以下两种验证模式:

1、普通模式(默认是这个模式)

  普通模式(会校验完所有的属性,然后返回所有的验证失败信息)

2、快速失败返回模式

  快速失败返回模式(只要有一个验证失败,则返回)

两种验证模式配置方式:(参考官方文档

failFast:true 快速失败返回模式 false 普通模式

.addProperty( "hibernate.validator.fail_fast", isDebugMode() ? "false": "true"  )

image-20200529145108074

兼容性

首先配置

.ignoreXmlConfiguration()

在低版本(api16,19)上报找不到Log_$logger;

IllegalArgumentException: Invalid logger interface org.hibernate.validator.internal.util.logging.Log (implementation not found)

解决方法: 将Log_$logger拷出来,包路径不变,类名改成常规名字即可:

image-20200529145128566

注意要编译成功,还需要依赖:

implementation group: 'javax.xml', name: 'jaxb-api', version: '2.1'
implementation group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.1'

至此,可兼容到api16

代码库:

AndroidBeanValidator

参考:

不吹不擂,提升你对BeanValidation数据校验的认知

SpringMVC中实现Bean Validation(JSR 303 JSR 349 JSR 380)

stackoverflow.com/questions/2…

hibernate.org/validator/d…