SpringMVC Validator验证示例

SpringMVC服务器验证一种是有两种方式,一种是基于Validator接口,一种是使用Annotaion JSR-303标准的验证,下面主要是学习这两种,工作中推荐后者,方便很多

一.基于Validator接口的验证.

首先创建User实例,并加入几个属性

public class User {
  private String username;
  private String password;
  private String nickname;

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getNickname() {
    return nickname;
  }

  public void setNickname(String nickname) {
    this.nickname = nickname;
  }

  @Override
  public String toString() {
    return "username--"+username+"password--"+password+"nickname--"+nickname;
  }
}

接着创建用于校检的类UserValidator,让其实现Validator,覆盖其中的两个方法

import main.java.model.User;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class UserValidator implements Validator {

  @Override
  public boolean supports(Class<?> aClass) {
    //判断是否是要校验的类,这里是User
    return User.class.equals(aClass);
  }

  @Override
  public void validate(Object o, Errors errors) {
    User u = (User) o;
    if (null == u.getPassword() || "".equals(u.getPassword())){
      //此方法可以加四个参数,第一个表单域field,
      //区分是哪个表单出错,第二个errorCode错误码,
      //第三个制定了资源文件中占位符,第四个具体错误返回信息
      //简写版可以把2,3参数去掉
      errors.rejectValue("password",null,null,"password is null");
    }
  }
}

上面的类只实现了对密码判断是否为空,为空则注册这一错误信息,也就是”password is null”,接下来要实现控制器,控制器要做的事情,第一是注册这个校验器,第二是实现校验.

import main.java.model.User;
......

/**
 * 加上@Controller决定这个类是一个控制器
 */
@Controller
@RequestMapping("/user")
public class HelloController {

  //我们知道在Controller类中通过@InitBinder标记的方法只有在请求当前Controller的时候才会被执行
  //所以在这里注册校验器
  @InitBinder
  public void initBainder(DataBinder binder){
    binder.replaceValidators(new UserValidator());

  }
  //这个方法主要是跳转到登录页面
  @RequestMapping(value = "/login",method = RequestMethod.GET)
  public String login(Model model){
    model.addAttribute(new User());
    return "user/login";
  }
  //处理登录表单
  @RequestMapping(value = "/login",method = RequestMethod.POST)
  public String login(@Validated User user, BindingResult br){

    if (br.hasErrors()){
      return "user/login";
    }
    return "--";
  }
  }

上面代码可以看到@Validated User user, BindingResult br这两个参数,@Validated表明参数user是要校验的类,BindingResult是存储错误信息的类,两者必须一一对应,并且位置挨着,不能中间有其他参数,

最后随便写一个jsp页面实现校检

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%
  request.setCharacterEncoding("utf-8");
%>
<html>
<head>
  <meta charset="utf-8">
  <title>用户登录</title>
</head>
<body>
  <sf:form modelAttribute="user" method="post">
    用户名:<sf:input path="username"/><sf:errors path="username"/>
    <br>
    密码:<sf:input path="password"/><sf:errors path="password"/>
    <br>
    昵称:<sf:input path="nickname"/><sf:errors path="nickname"/>
    <br>
    <input type="submit" value="提交">
  </sf:form>
</body>
</html>

前面实现的是局部校验,只对当前控制器有效,如果要实现全局校验的话需要配置springMVC.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/mvc
   http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

  <mvc:annotation-driven validator="userValidator"/>

  <bean id="userValidator" class="com.xxx.xxx.UserValidator"/>

  ...
</beans>

二.使用Annotaion JSR-303标准的验证

使用这个需要导入支持JSR-303标准的包,建议使用hibernate Validator这个包,先看这个标准的原生标注

限制 说明
@Null 限制只能为null
@NotNull 限制必须不为null
@AssertFalse 限制必须为false
@AssertTrue 限制必须为true
@DecimalMax(value) 限制必须为一个不大于指定值的数字
@DecimalMin(value) 限制必须为一个不小于指定值的数字
@Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
@Future 限制必须是一个将来的日期
@Max(value) 限制必须为一个不大于指定值的数字
@Min(value) 限制必须为一个不小于指定值的数字
@Past 限制必须是一个过去的日期
@Pattern(value) 限制必须符合指定的正则表达式
@Size(max,min) 限制字符长度必须在min到max之间
@Past 验证注解的元素值(日期类型)比当前时间早
@NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
@NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

要使用很简单,在需要验证的变量前面加上该Annotation即可,看下面使用后的User

public class User {
  @NotEmpty(message = "用户名不能为空")
  private String username;
  @Size(min=6 ,max= 20 ,message = "密码长度不符合标准")
  private String password;
  private String nickname;

  ......
}

然后再控制器里面加入验证就可以了

@Controller
@RequestMapping("/user")
public class HelloController {

  @RequestMapping(value = "/login",method = RequestMethod.GET)
  public String login(Model model){
    model.addAttribute(new User());
    return "user/login";
  }

  @RequestMapping(value = "/login",method = RequestMethod.POST)
  public String login(@Validated User user, BindingResult br){

    if (br.hasErrors()){
      return "user/login";
    }
    return "user/login";
  }
  }

然后jsp页面还是之前的页面,验证效果如下,这种方法明显简单多了

3.定义自己的Annotation Validator

这部分直接从[大牛][1]那拷贝过来的.

除了JSR-303原生支持的限制类型之外我们还可以定义自己的限制类型。定义自己的限制类型首先我们得定义一个该种限制类型的注解,而且该注解需要使用@Constraint标注。现在假设我们需要定义一个表示金额的限制类型,那么我们可以这样定义:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

import com.xxx.xxx.constraint.impl.MoneyValidator;

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MoneyValidator.class)
public @interface Money {

  String message() default"不是金额形式";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

}

我们可以看到在上面代码中我们定义了一个Money注解,而且该注解上标注了@Constraint注解,使用@Constraint注解标注表明我们定义了一个用于限制的注解。@Constraint注解的validatedBy属性用于指定我们定义的当前限制类型需要被哪个ConstraintValidator进行校验。在上面代码中我们指定了Money限制类型的校验类是MoneyValidator。另外需要注意的是我们在定义自己的限制类型的注解时有三个属性是必须定义的,如上面代码所示的message、groups和payload属性。

在定义了限制类型Money之后,接下来就是定义我们的限制类型校验类MoneyValidator了。限制类型校验类必须实现接口javax.validation.ConstraintValidator,并实现它的initialize和isValid方法。我们先来看一下MoneyValidator的代码示例:

import java.util.regex.Pattern;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import com.xxx.xxx.constraint.Money;

public class MoneyValidator implements ConstraintValidator<Money, Double> {

  private String moneyReg = "^\\d+(\\.\\d{1,2})?$";//表示金额的正则表达式
  private Pattern moneyPattern = Pattern.compile(moneyReg);

  public void initialize(Money money) {
    // TODO Auto-generated method stub

  }

  public boolean isValid(Double value, ConstraintValidatorContext arg1) {
    // TODO Auto-generated method stub
    if (value == null)
      return true;
    return moneyPattern.matcher(value.toString()).matches();
  }

}

从上面代码中我们可以看到ConstraintValidator是使用了泛型的。它一共需要指定两种类型,第一个类型是对应的initialize方法的参数类型,第二个类型是对应的isValid方法的第一个参数类型。从上面的两个方法我们可以看出isValid方法是用于进行校验的,有时候我们在校验的过程中是需要取当前的限制类型的属性来进行校验的,比如我们在对@Min限制类型进行校验的时候我们是需要通过其value属性获取到当前校验类型定义的最小值的,我们可以看到isValid方法无法获取到当前的限制类型Money。这个时候initialize方法的作用就出来了。

我们知道initialize方法是可以获取到当前的限制类型的,所以当我们在校验某种限制类型时需要获取当前限制类型的某种属性的时候,我们可以给当前的ConstraintValidator定义对应的属性,然后在initialize方法中给该属性赋值,接下来我们就可以在isValid方法中使用其对应的属性了。针对于这种情况我们来看一个代码示例,现在假设我要定义自己的@Min限制类型和对应的MinValidator校验器,那么我可以如下定义:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=MinValidator.class)
public @interface Min {

  int value() default 0;

  String message();

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};
}
MinValidator校验器
public class MinValidator implements ConstraintValidator<Min, Integer> {

  private int minValue;

  public void initialize(Min min) {
    // TODO Auto-generated method stub
    //把Min限制类型的属性value赋值给当前ConstraintValidator的成员变量minValue
    minValue = min.value();
  }

  public boolean isValid(Integer value, ConstraintValidatorContext arg1) {
    // TODO Auto-generated method stub
    //在这里我们就可以通过当前ConstraintValidator的成员变量minValue访问到当前限制类型Min的value属性了
    return value >= minValue;
  }

}

继续来说一下ConstraintValidator泛型的第二个类型,我们已经知道它的第二个类型是对应的isValid的方法的第一个参数,从我给的参数名称value来看也可以知道isValid方法的第一个参数正是对应的当前需要校验的数据的值,而它的类型也正是对应的我们需要校验的数据的数据类型。这两者的数据类型必须保持一致,否则spring会提示找不到对应数据类型的ConstraintValidator。建立了自己的限制类型及其对应的ConstraintValidator后,其用法跟标准的JSR-303限制类型是一样的。以下就是使用了上述自己定义的JSR-303限制类型——Money限制和Min限制的一个实体类:

public class User {

  private int age;

  private Double salary;

  @Min(value=8, message="年龄不能小于8岁")
  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Money(message="标准的金额形式为xxx.xx")
  public Double getSalary() {
    return salary;
  }

  public void setSalary(Double salary) {
    this.salary = salary;
  }

}

4.配合ajax验证

最近写的项目,感觉直接使用validator不太好用,主要是返回时会刷新整个页面才会出来错误信息,体验相当不好,验证还是用ajax体验比较好,所以配合ajax

思路:验证还是使用springMVC来验证,只是这次发现错误的话,把错误取出,存放到一个map中,然后ajax返回,页面根据ajax返回值来判断,从而显示不同的信息

主要代码:

 if (br.hasErrors()){//判断是否有错误
       //对错误集合进行遍历,有的话,直接放入map集合中
      br.getFieldErrors().forEach(p->{
        maps.put(p.getField(),p.getDefaultMessage());
      });
      return maps;
    }

这样的话 maps里面存放的就是 错误变量名,错误信息,例如 username -‘用户名不能为空'

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • JSP中springmvc配置validator的注意事项

    SpringMVC介绍之Validation 对于任何一个应用而言在客户端做的数据有效性验证都不是安全有效的,这时候就要求我们在开发的时候在服务端也对数据的有效性进行验证.SpringMVC自身对数据在服务端的校验有一个比较好的支持,它能将我们提交到服务端的数据按照我们事先的约定进行数据有效性验证,对于不合格的数据信息SpringMVC会把它保存在错误对象中,这些错误信息我们也可以通过SpringMVC提供的标签在前端JSP页面上进行展示. 关于springmvc配置validator的注意事项

  • BootStrap与validator 使用笔记(JAVA SpringMVC实现)

    BootStrap 是一个强大的前面框架,它用优雅的方式解决了网页问题.最近正在使用其开发网站的表单验证,一点体会记录如下: 注:本文中借鉴了博客Franson 的文章使用bootstrap validator的remote验证代码经验分享(推荐) 一.准备工作 1.你的网站环境中要有 BootStrap,中文网地址:http://www.bootcss.com/ 2.下载BootStrap Validator相关材料,地址:http://bv.doc.javake.cn/ 当然,如果你不想一个

  • springmvc的validator数据校验的实现示例代码

    一.什么是数据校验? 这个比较好理解,就是用来验证客户输入的数据是否合法,比如客户登录时,用户名不能为空,或者不能超出指定长度等要求,这就叫做数据校验. 数据校验分为客户端校验和服务端校验 客户端校验:js校验 服务端校验:springmvc使用validation校验,struts2使用validation校验.都有自己的一套校验规则. 二.springmvc的validation校验 Springmvc本身没有校验功能,它使用hibernate的校验框架,hibernate的校验框架和orm

  • SpringMVC Validator验证示例

    SpringMVC服务器验证一种是有两种方式,一种是基于Validator接口,一种是使用Annotaion JSR-303标准的验证,下面主要是学习这两种,工作中推荐后者,方便很多 一.基于Validator接口的验证. 首先创建User实例,并加入几个属性 public class User { private String username; private String password; private String nickname; public String getUsernam

  • SpringBoot集成SpringMVC的方法示例

    Spring MVC是一款优秀的.基于MVC思想的应用框架,它是Spring的一个子框架.是当前最优秀的MVC框架. Spring Boot整合Spring MVC只需在pom.xml中引入 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.3.7.RE

  • vue表单验证rules及validator验证器的使用方法实例

    目录 前言 表单验证rules 自定义校验规则 总结 前言 为防止用户犯错,尽可能更早地发现并纠正错误. Element中Form (表单)组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,并将 Form-Item 的 prop 属性设置为需校验的字段名即可. 注意:prop对应表单域 model 字段,使用 validate方法时,该属性是必填的. 表单验证rules 以官网给出的例子分析来看 将prop 属性设置为需校验的字段名. 在data里配置要校验字段和校验规则

  • jQuery Validator验证Ajax提交表单的方法和Ajax传参的方法

    serialize() 方法通过序列化表单值,创建 URL 编码文本字符串.代替了一个一个传参的方式 以往写的ajax传参方式 $.ajax({ url : "${ctx}/SJStandardDamPartition/insertOrUpdateDamPartition", type : "post", dataType : "json", data: {beginsectionid:function(){ return $('#number

  • javascript中使用正则表达式进行字符串验证示例

    var reg=/正则表达式/: boolean reg.test(要验证的字符串); js引擎会将/正则表达式/""转换成一个RegExp对象,当字符串满足正则表达式的要求事,返回true. 我写的一个表达式验证示例:功能如下: 用户名,不能为空 密码6为数字 密码确认,两次输入密码必须相同 身份证号码必须是15位,或者是18位,最末尾也可以是X(该功能还没有写,有时间再补上) 复制代码 代码如下: <!DOCTYPE html> <html> <hea

  • JavaScript 基础表单验证示例(纯Js实现)

    验证思路 监听每个input控件的焦点离开(onblue),当焦点离开时调用验证函数,验证后修改第三栏文字,显示符合/不符合并返回true/false 实现代码: index.html <!DOCTYPE html> <html> <head> <title></title> <pnk rel="stylesheet" href="css.css" rel="external nofollo

  • Laravel4中的Validator验证扩展用法详解

    本文实例讲述了Laravel4中的Validator验证扩展用法.分享给大家供大家参考,具体如下: 不管写接口还是写web页面,实质都是传入参数,然后进行业务逻辑,然后再输出具体内容.所以,对参数的验证是不可避免的一个环节,比如传过来的email是不是为空,是不是合法的email格式?laravel已经为phper想到简化这种逻辑的办法了.就是Validator. Validator的使用 制造一个验证器 validator使用Validator::make可以制造一个验证器.然后使用验证器判断

  • SpringMVC适配器模式代码示例

    此处采用了适配器模式, 由于Controller的类型不同,有多重实现方式,那么调用方式就不是确定的,如果需要直接调用Controller方法,需要在代码中写成如下形式: if(mappedHandler.getHandler() instanceof MultiActionController){ ((MultiActionController)mappedHandler.getHandler()).xxx }else if(mappedHandler.getHandler() instanc

  • JavaScript表单验证示例详解

    HTML表单(form)通常用于收集用户信息,例如姓名,电子邮件地址,位置,年龄等. 但是很可能某些用户可能不会输入您期望的数据.HTML表单验证可以通过JavaScript完成. 为了避免对服务器资源造成不必要的压力,您可以使用JavaScript在客户端(用户系统)上验证表单数据,不正确的信息是不会提交给后台服务器的--这是所谓客户端验证.本文将介绍这种验证 表单验证一般分为两种方式. 客户端验证:直接在客户端执行JS进行验证,验证的过程中和服务器端没有任何的交互 服务器端验证:页面将验证信

  • java开发的工厂方法模式及抽象工厂验证示例

    目录 工厂方法模式示例 抽象工厂模式验证 结论 工厂方法模式示例 开发一个数据格式转换工具,将不同数据源如:txt.excel等格式文件,转换为XML格式输出,需考虑今后其他格式的文件也需要转换为xml格式的扩展性,利用设计模式的有关知识进行设计. 解决思路,使用工厂方法模式完成该功能的设计,设计类图如下: 代码结构如下: 代码如下: public interface Creator { Convertor getConvertor(); } public class ExcelConverto

随机推荐