SpringMVC 表单验证

本文探讨了在Spring MVC中优雅地处理客户端数据验证的方法,主要关注Spring对JSR-303 Bean Validation API的集成。文章通过示例介绍了如何使用Hibernate Validator的内置验证注解,并讲解了如何自定义验证约束注解及其处理类,以身份证验证为例,展示了不同身份群体的身份认证验证策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   在开发过程中经常会遇到对客户端传输过来的数据进行验证,传入的数据不是数字类型,传入的身份证信息格式不对,等等。

之前是通过工具类来一个判断,那么显然这种方法就有些笨拙了,那么在Spring中 我们如何优雅的来处理这些问题?

对于Valication 这块,Spring 大体有两种机制。

一种是Spring的:org.springframework.validation.Validator

另一种是Spring JSR-303 Bean Validation API的集成了:javax.validation.Validator

这里我们主要讨论一下第二种。

首先我们来看一下Spring对数据验证的具体做法,这里引用一个官方实例来进行说明:

  Foo target = new Foo();     	
  DataBinder binder = new DataBinder(target);
  // 添加验证器	
  binder.setValidator(new FooValidator());	
  // 将请求参数绑定到Foo类上	
  binder.bind(propertyValues);	
  // 数据验证	
  binder.validate();	
  // 获得验证结果	
  BindingResult results = binder.getBindingResult();
  // result.getFieldError();
在控制器(@Controller)中我们可以使用如下方式开启验证。

public void companySignup(@Valid UserForm userForm,BindingResult result){    
      if (result.hasErrors()) {
        //开始处理错误        
        FieldError  error =  result.getFieldError();    
      }
}

对于规范中内置的一些实用验证 可以引入Hibernate Validator 的实现。

以下为出几个内置注解

  @AssertFalse(message = "暂未开通海外业务")
  //message 中的信息可以在BindingResult中获得private Boolean foreigner;
  @Min(value=10)private int income;
  @Past
  //时间必须是之前的
  private Date birthday;
  @NotNullpublic String remark;
  @Pattern(regexp = "^[1][3,4,5,7,8][0-9]{9}$")
  public String mobilePhone;
  @Size(min = 6,max = 30)
  public String name;

有内置当然就允许自定义了,那么我们来看一下自定义的验证器怎么来实现。

自定义验证比较简单,主要就是定义一个验证约束就可以了。

一个验证约束注解及对应的处理类。

我们就已验证身份证来进行设计,假设我们的用户分成了两类群体,一类是身份证群体,一类是护照群体。

其性质来看都属于身份认证,但验证手段有所不同。

约束注解
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
//这行注解 标识此注解式一个验证约束注解,需要绑定一个能处理该约束的处理器 这里用了IdcardConstraintor
@Constraint(validatedBy =IdcardConstraintor.class)
public @interface IdcardCheck {   
       /**     
        * 以下三个 是 自定义验证约束必需实现的方法     
        */    
        String message() default "";    
        Class<?>[] groups() default { };    
        Class<? extends Payload>[] payload() default { };    
      /**     
       * 这个属性来确定是验证类型 [身份证,护照]     
       */    
        IdcardType type() default IdcardType.ID;    
      enum IdcardType{        
          ID,PASSPORT    
      }
}

约束注解对应的处理器:
public class IdcardConstraintor implements ConstraintValidator<IdcardCheck,String> {    
        private IdcardCheck.IdcardType  type;       
       /**    
        * Spring 会为每个使用了@IdcardCheck的字段对应一个实例,即处理器不是单例的。    
        * 所以可以在这里进行一些 初始化操作        
        */   
         @Override    
        public void initialize(IdcardCheck idcardCheck) {      
             this.type = idcardCheck.type();    
        }
    
        @Override    
        public boolean isValid(String value, ConstraintValidatorContext context) {
              if (this.type == IdcardCheck.IdcardType.ID) {   
         
                  return IdcardUtils.verifyID(value);       
              }
              else if(this.type == IdcardCheck.IdcardType.PASSPORT){      
                  return IdcardUtils.verifyPassword(value);        
              }        
              throw new IllegalArgumentException(type + " can't find a handler");    
      }
}

OK 接收form类上面就可以进行使用了:
public class UserForm {   
   private String username;    
   @Email
   //该注解式Hibernate实现里面内带的    
   private String email;   
   @Pattern(regexp = "^[1][3,4,5,7,8][0-9]{9}$",message = "It is  not  a  valid mobile phone")   
   private String mobilePhone;    
   private String password;       
   @IdcardCheck(type = IdcardCheck.IdcardType.ID)   
   private String idcard;
}

OK 这样自定义的验证 就可以投入使用了,最后粘贴一下可能会用到的maven 信息
  <dependency>    
    <groupId>org.hibernate</groupId>    
    <artifactId>hibernate-validator</artifactId> 
     <version>5.2.0.Final</version>
  </dependency>
   
  <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
  </dependency>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值