SpringMVC集成Hibernate Validator进行参数校验

1、JSR303

 JSR303是java为Bean数据合法性校验所提供的标准框架,它已经包含在java EE6.0中。JSR303通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证。


Hibernate Validator是JSR303的一个参考实现,除支持所有标准的校验注解外,它还支持扩展注解。


2、Spring校验框架

 Spring3.0拥有自己独立的数据校验框架,同时支持JSR303标准的校验框架。Spring的DataBinder在进行数据绑定时,可同时调用校验框架完成数据校验工作。

 Spring的org.springframework.validator是校验框架所在的包,LocalValidatorFactoryBean既实现了Spring的Validator接口,也实现了JSR 303的Validator接口。只要在Spring容器中定义一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的Bean中。

  <mvc:annotation-driven validator="validator"/>
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
    </bean>
  Spring本身没有提供JSR303的实现,所以必须将JSR303的实现者(如Hibernate Validator)的jar文件放到类路径下,Spring将其自动加载并装配好JSR 303的实现者。

3、SpringMVC数据校验

 <mvc:annotation-driven />默认的会装配好一个LocalValidatorFactoryBean,通过在方法参数上标注@Valid注解即可让Spring MVC在完成数据绑定后执行数据校验的工作,例:

  • 首先在bean上注解规则

public class AccountParam {
    @NotBlank(message = "{username}")
    private String username;
    @NotBlank(message = "{passwd}")
    private String passwd;
    @NotNull
    @Pattern(regexp = ".*(?=.*\\d)(?=.*[a-zA-Z])(?=.*[~!@#$%^&*_]).{8,}")
    private String newpasswd;
    @NotBlank(message = "{confirmpasswd}")
    private String confirmpasswd;
}

  • 在Controller中对方法参数注解声明校验
/修改密码
    @RequestMapping(value = "/update-account", method = RequestMethod.POST)
    @ResponseBody
    public AjaxResult updateUserPasswd(HttpServletRequest request, @Valid AccountParam accountParam, BindingResult bindingResult) {
        logger.info("AccountController updateUserPasswd:/update-account?param={}", accountParam.toString());
        if (bindingResult.hasErrors()) {
            return AjaxResult.errorParam();
        }
}

需要校验的表单/命令对象和其绑定结果对象或错误对象是成对出现的,他们之间不允许声明其他的入参。

4、组校验

 有的时候,我们对一个实体类需要有多种验证方式,在不同的情况下使用不同的验证方式,比如说对于网络配置来说,静态地址配置方式需要我们队ip、子网掩码、网段等格式进行校验,而DHCP时不需要输入这些。当一个Bean需要不同的校验规则时就需要分组。

  • 首先定义两个组

public interface DhcpGroup {
}
public interface StaticGroup {
}

  • 在实体类由组区分不同的规则
public class NetworkParam {
    @NotBlank
    private String eth;
    @NotNull(groups = {StaticGroup.class,DhcpGroup.class})
    @Pattern(regexp = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$", groups = StaticGroup.class)
    private String ip;
    @NotNull(groups = {StaticGroup.class,DhcpGroup.class})
    @Pattern(regexp = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$", groups = StaticGroup.class)
    private String netmask;
    @NotNull(groups = {StaticGroup.class,DhcpGroup.class})
    @Pattern(regexp = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$", groups = StaticGroup.class)
    private String gateway;
    @NotNull(groups = {StaticGroup.class,DhcpGroup.class})
    @Pattern(regexp = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$", groups = StaticGroup.class)
    private String dns1;
    @NotNull(groups = {StaticGroup.class,DhcpGroup.class})
    @Pattern(regexp = "^((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]|[*])$", groups = StaticGroup.class)
    private String dns2;
    @NotNull(groups = {StaticGroup.class,DhcpGroup.class})
    private Integer isDhcp;
}
在Controller中指定组来对不同的情况进行校验。

 //静态配置网络
    @RequestMapping(value = "/set-netconfig-static", method = RequestMethod.POST)
    @ResponseBody
    public AjaxResult setNetconfigStatic(HttpServletRequest request, @Validated({StaticGroup.class}) NetworkParam networkParam, BindingResult bindingResult) throws IOException {
        logger.info("NetconfigController setNetConfigStatic:/set-netconfig-static?params={}", networkParam.toString());
        if (bindingResult.hasErrors()) {
            return AjaxResult.errorParam();
        }
}
 //DHCP配置网络
    @RequestMapping(value = "/set-netconfig-dhcp", method = RequestMethod.POST)
    @ResponseBody
    public AjaxResult setNetconfigDhcp(HttpServletRequest request, @Validated({DhcpGroup.class}) NetworkParam networkParam, BindingResult bindingResult) throws IOException {
        logger.info("NetconfigController setNetConfigDhcp:/set-netconfig-dhcp?params={}", networkParam.toString());
        if (bindingResult.hasErrors()) {
            return AjaxResult.errorParam();
        }
}

  • 控制组的校验顺序

 @GroupSequence({Group1.class,Group2.class,User.class})来控制校验顺序,即先校验group1再校验group2

参考:

https://www.jianshu.com/p/fc6c20af759a

https://www.cnblogs.com/hujihon/p/5357481.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值