您的位置:首页 > 运维架构 > Apache

数据验证框架 Apache BVal 简介

2016-01-28 16:10 543 查看
Apache BVal源码)是实体数据验证 Java Bean Validation 的参考实现。Apache BVal 提供了 JSR 303 规范中所有内置 constraint 的实现,用于对 Bean 中的字段的值进行约束定义、描述和验证。若单单说 JSR 规范大渣可能还不清楚,但做过 POJO 的 Hibernate Validator 注解的朋友就知道是啥,——那为什么不使用主流的 Hibernate Validator 呢?因为这货净是个压缩包都已经 13mb 了(尽管可以有文档、源码其他在内),BVal 才只有 400 多 kb,而我只需要服务端验证而已,——天真的孩纸伤不起啊。俺的 ORM 也是 Mybatis 的,务求尽可能地轻量级。



Spring MVC 3.x 虽然自带了验证器 Validatior,可以在控制器中对表单提交的数据进行验证,但这个验证器是极其弱,因为你需要完全手工编码 if (null) else warn("不能空数据"),——太变态了(入下面的例子)——我们需要框架来减轻费时耗力的劳动,于是这类验证框架出现了。
import org.springframework.validation.Errors;  
    import org.springframework.validation.ValidationUtils;  
    import org.springframework.validation.Validator;  
       
    public class UserValidator implements Validator {  
       
        public boolean supports(Class<?> clazz) {  
           // TODO Auto-generated method stub  
           return User.class.equals(clazz);  
        }  
       
        public void validate(Object obj, Errors errors) {  
           // TODO Auto-generated method stub  
           ValidationUtils.rejectIfEmpty(errors, "username", null, "Username is empty.");  
           User user = (User) obj;  
           if (null == user.getPassword() || "".equals(user.getPassword()))  
               errors.rejectValue("password", null, "Password is empty.");  
        }  
       
    }
而我们理想的是这样的,在 POJO 身上声明验证条件的注解:
import javax.validation.constraints.Min;  
import javax.validation.constraints.NotNull;  
import org.hibernate.validator.constraints.NotBlank;  
   
public class User {  
    private String username;    
    private String password;  
    private int age;  
   
    @NotBlank(message="用户名不能为空")  
    public String getUsername() {  
       return username;  
    }  
    public void setUsername(String username) {  
       this.username = username;  
    }  

    @NotNull(message="密码不能为null")  
    public String getPassword() {  
       return password;  
    }  
    public void setPassword(String password) {  
       this.password = password;  
    }  
   
    @Min(value=10, message="年龄的最小值为10")  
    public int getAge() {  
       return age;  
    }  
    public void setAge(int age) {  
       this.age = age;  
    }  
}
如果用 Apache BVal 是怎么做的呢?首先准备一下 jar 包:



接着,我们仍旧离不开 Spring,在 MVC 的 xml 配置文件中加入以下:
<mvc:annotation-driven validator="validator"/>

<!-- 数据验证 Validator bean -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
    <property name="providerClass" value="org.apache.bval.jsr.ApacheValidationProvider" />
</bean>
<!-- // -->
这是一种全局的配置方式,我们注入 Bval 的验证器,另外,还要让 MVC 打开注解驱动。加上了 <mvn:annotation-driven/> 之后 Spring 会自动检测 classpath 下的 JSR-303 提供者并自动启用对 JSR-303 的支持。然后就可以在 POJO 中添加注解,而且要在控制器中声明 bean 的验证,如下例的 @Valid T news,否则 Bval 不会起作用。
/**
 * 新建 
 * @return
 */
@RequestMapping(method = RequestMethod.POST)
public String create(@Valid T news,  BindingResult result,Model model) {
	System.out.println("新建");
	if (result.hasErrors()) {
		LOGGER.info("create error!");
	}else{
		LOGGER.info("create ok!");
	}
	news.setService(getService());
	try {
		getService().create(news);
		model.addAttribute("newlyId", news.getId());
	} catch (ServiceException e) {
		model.addAttribute("errMsg", e.toString());
	}
	
	return "common/entity/json_cud";
}
一定要注意的是,控制器方法的参数顺序。Binding Result 必须在 Bean 后面。这是 Spring MVC 的约定。MVC 对控制器其他参数的顺序没什么规定,唯独这个 BindingResult 作了如此规定。目的是为了可以允许有多个 bean,于是也就有多个 BindingResult。
怎么处理错误就不详细说了,不同场景下要求不同。
可否自定义验证条件?我还没试,应该可以参考 Hibernate Validator 的做法。下面这篇文章说得很详细。
《Springmvc validator 验证的使用》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: