06数据验证

  • 声明式数据验证
  • 内置的验证约束和注解
  • 错误消息
  • 功能处理方法上多个验证参数的处理
  • 异常处理的支持

1      声明式数据验证

Spring3开始支持JSR-303验证框架,JSR-303支持XML风格的和注解风格的验证,接下来我们首先看一下如何使用Spring的验证功能。

 1、添加jar包  

此处使用Hibernate-validator实现(版本:hibernate-validator-4.3.0.Final-dist.zip),将如下jar包添加到classpath(WEB-INF/lib下即可):

  • dist/lib/required/validation-api-1.0.0.GA.jar JSR-303规范API包
  • dist/hibernate-validator-4.3.0.Final.jar Hibernate 参考实现
  • 还需要加入jboss-logging-3.1.0.CR2.jarFormatter SPI简介

2、在Spring配置中添加对JSR-303验证框架的支持

<!-- 以下validator ConversionService 在使用mvc:annotation-driven 会自动注册-->

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">

    <property name="providerClass" value="org.hibernate.validator.HibernateValidator" />

    <!-- 如果不加默认到使用classpath下的 ValidationMessages.properties -->

    <property name="validationMessageSource" ref="messageSource" />

</bean>


3
、在Spring配置中添加message配置

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">

     <property name="basename" value="classpath:messages"/>

     <property name="fileEncodings" value="utf-8"/>

     <property name="cacheSeconds" value="120"/>

</bean>

username.not.empty= =\u7528\u6237\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A在src下放一个messages.properties,里面的内容是:

这是已经转义的,原始的信息是:用户姓名不能为空

将校验器注入到处理器适配器中

<!-- 校验器注入到处理器适配器中 -->

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

使用JSR-303验证框架注解为模型对象指定验证信息。

4、  HelloWorld的Model

public class UserModel {

@NotNull(message="{username.not.empty}")

private String username;

省略get/set……

}

通过@NotNull指定此username字段不允许为空,当验证失败时将从之前指定的messageSource中获取“username.not.empty”对于的错误信息,此处只有通过“{错误消息键值}”格式指定的才能从messageSource获取。

5、  HelloWorld的Controller

@Controller

public class HelloWorldController {

    @RequestMapping("/validate/hello")

    public String validate(@Valid @ModelAttribute("user") UserModel user, Errors errors) {

        if (errors.hasErrors()) {

            return "validate/error";

        }

        return "validate/success";

    }

}

说明:错误对象的代表者是Errors接口,并且提供了几个实现者,在Spring Web MVC中我们使用的是如下实现:Errors、BindingResult、BindException等通过在命令对象上注解@Valid来告诉Spring MVC此命令对象在绑定完毕后需要进行JSR-303验证,如果验证失败会将错误信息添加到errors错误对象中

6、  HelloWorld的验证失败后需要展示的页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<form:form commandName="user">

    <form:errors path="*"   cssStyle="color:red"></form:errors><br/>

</form:form>

可以去测试啦,不给UserModel传递name值看看效果。

测试地址:

http://localhost:8088/06springMVC/validate/hello?username=999

http://localhost:8088/06springMVC/validate/hello

2      内置的验证约束和注解

@AssertFalse

验证的数据类型:Boolean,boolean

说明:验证注解的元素值是false

 @AssertTrue

验证的数据类型:Boolean,boolean

说明:验证注解的元素值是true

@NotNull

验证的数据类型:任意类型

说明:验证注解的元素值不是null

@Null

验证的数据类型:任意类型

说明:验证注解的元素值是null

@Min(value=值)

验证的数据类型:BigDecimal,BigInteger, byte,short, int, long,等任何Number或CharSequence(存储的是数字)子类型

说明:验证注解的元素值大于等于@Min指定的value值

@Max(value=值)

验证的数据类型:和@Min要求一样

说明:验证注解的元素值小于等于@Max指定的value值

@DecimalMin(value=值)

验证的数据类型:和@Min要求一样

说明:验证注解的元素值大于等于@ DecimalMin指定的value值

@DecimalMax(value=值)

验证的数据类型:和@Min要求一样

说明:验证注解的元素值小于等于@ DecimalMax指定的value值

@Digits(integer=整数位数, fraction=小数位数)

验证的数据类型:和@Min要求一样

说明:验证注解的元素值的整数位数和小数位数上限

@Size(min=下限, max=上限)

验证的数据类型:字符串、Collection、Map、数组等

说明:验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小

@Past

验证的数据类型:java.util.Date,java.util.Calendar,Joda Time类库的日期类型

说明:验证注解的元素值(日期类型)比当前时间早

@Future

验证的数据类型:与@Past要求一样

说明:验证注解的元素值(日期类型)比当前时间晚

@NotBlank

验证的数据类型:CharSequence子类型

说明:验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty

@NotBlank只应用于字符串且在比较时会去除字符串的首位空格

@Length(min=下限, max=上限)

验证的数据类型: CharSequence子类型

说明:验证注解的元素值长度在min和max区间内

@NotEmpty

验证的数据类型:CharSequence子类型、Collection、Map、数组

说明:验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)

@Range(min=最小值, max=最大值)

验证的数据类型:BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型

说明:验证注解的元素值在最小值和最大值之间

@Email(regexp=正则表达式,flag=标志的模式)

验证的数据类型:CharSequence子类型(如String)

说明:验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式

@Pattern(regexp=正则表达式,flag=标志的模式)

验证的数据类型:String,任何CharSequence的子类型

说明:验证注解的元素值与指定的正则表达式匹配

@Valid

验证的数据类型:任何非原子类型

说明:指定递归验证关联的对象;如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加@Valid注解即可级联验证

注意:

此处只列出Hibernate Validator提供的大部分验证约束注解,请参考hibernatevalidator官方文档了解其他验证约束注解和进行自定义的验证约束注解定义

3      错误消息

当验证出错时,我们需要给用户展示错误消息告诉用户出错的原因,因此我们要为验证约束注解指定错误消息。错误消息是通过在验证约束注解的message属性指定。验证约束注解指定错误消息有如下两种方式:

1、硬编码错误消息;

2、从资源消息文件中根据消息键读取错误消息。

硬编码错误消息

直接在验证约束注解上指定错误消息,如下所示:

@NotNull(message = "用户名不能为空")

@Length(min=5, max=20, message="用户名长度必须在5-20之间")

@Pattern(regexp = "^[a-zA-Z_]\\w{4,19}$", message = "用户名必须以字母下划线开头,可由字母数字下划线组成")

private String username;

如上所示,错误消息使用硬编码指定,这种方式是不推荐的,因为在如下场景是不适用的:

1、在国际化场景下,需要对不同的国家显示不同的错误消息;

2、需要更换错误消息时是比较麻烦的,需要找到相应的类进行更换,并重新编译发布。

从资源消息文件中根据消息键读取错误消息

这个最为推荐的方式就是直接使用Spring的MessageSource Bean进行消息的匹配和管理,前面的案例就是使用的这个方式,这儿就不赘述了。

4      功能处理方法上多个验证参数的处理

当我们在一个功能处理方法上需要验证多个模型对象时,需要通过如下形式来获取验证结果:

@RequestMapping("/validate/multi")

public String multi(

@Valid @ModelAttribute("a") A a, BindingResult aErrors,

@Valid @ModelAttribute("b") B b, BindingResult bErrors) {

  if(aErrors.hasErrors()) { //如果a模型对象验证失败

     return "validate/error";

  }

  if(bErrors.hasErrors()) { //如果a模型对象验证失败

     return "validate/error";

   }

  return " validate/success";

}

每一个模型对象后边都需要跟一个Errors或BindingResult对象来保存验证结果,其方法体内部可以使用这两个验证结果对象来选择出错时跳转的页面。

在错误页面,需要针对不同的模型来显示错误消息:

<form:form commandName="a">

    <form:errors path="*" cssStyle="color:red"></form:errors><br/>

</form:form>

<form:form commandName="b">

    <form:errors path="*" cssStyle="color:red"></form:errors><br/>

</form:form>

然后就可以测试了。

5      异常处理的支持

Spring Web MVC对异常处理的支持有三种方式:

1:一种是直接实现自己的HandlerExceptionResolver ,通常用来实现全局异常控制

2:Spring Web MVC已经有了一个缺省的实现:SimpleMappingExceptionResolver,

3:用注解的方式实现一个专门用于处理异常的Controller——ExceptionHandler,通常用来在Controller内部实现更个性化点异常处理方式,灵活性更高。

自定义实现的方式,只需要实现HandlerExceptionResolver接口即可,示例如下:

public class MyExceptionHandler implements HandlerExceptionResolver {

    public ModelAndView resolveException(HttpServletRequest request,

            HttpServletResponse response, Object handler, Exception ex) {

        if (ex instanceof NullPointerException) {

            // 这里就写如何处理,比如:记日志

            System.out.println("now is NullPointer 01");

        } else if (ex instanceof ArrayIndexOutOfBoundsException) {

            // 这里就写如何处理,比如:记日志

        }

        return new ModelAndView("/error/nullPage1");

    }

}

上述类需要在spring的配置文件中配置,示例如下:

<bean id="myExceptionHandler" class="cn.javass.springmvc.exception.MyExceptionHandler"/>

说明:

1:上述示例的resolveException方法的第四个参数,就是具体的例外类型

2:如果该方法返回了null,则Spring会继续寻找其他的实现了HandlerExceptionResolver 接口的Bean。也就是说,Spring会搜索 所有注册在其环境中的实现了HandlerExceptionResolver接口的Bean,逐个执行,直到返回了一个ModelAndView对象。

 

典型的异常显示页面示例如下:

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<body>

    <% Exception ex = (Exception) request.getAttribute("ex"); %>

    <H2>Exception: <%=ex.getMessage()%></H2>

    This is my nullPage1 page.

    <br>

</body>

</html>

测试方法示例:

@RequestMapping("test")    

public void test() {    

    throw new NullPointerException("出错了!");    

}   

当然我们也可以直接使用Spring提供的SimpleMappingExceptionResolver类,示例如下:

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

<!-- 定义默认的异常处理页面,当该异常类型的注册时使用-->

<property name="defaultErrorView" value="exception"></property>

<!-- 定义异常处理页面用来获取异常信息的变量名,默认名为exception -->

<property name="exceptionAttribute" value="ex"></property>

 <!-- 定义需要特殊处理的异常,用类名或完全路径名作为key,异常显示的页面名作为值-->

 <property name="exceptionMappings">

      <props>

        <prop key="NullPointerException">error/nullPage3</prop>

        <prop key="ArrayIndexOutOfBoundsException">error/ArrayIndexOutOfBoundsPage</prop>

      </props>

</property>

</bean>

说明:出了错过后,例外信息会以ex为key存放在request属性里面,因此在错误页面就可以通过request的属性取到例外对象了

基于@ExceptionHandler的异常处理

该方法需要定义在Controller内部,然后创建一个方法并用@ExceptionHandler注解来修饰用来处理异常,这个方法基本和@RequestMapping修饰的方法差不多,只是可以多一个类型为Exception的参数,@ExceptionHandler中可以添加一个或多个异常的类型,如果为空的话则认为可以触发所有的异常类型错误。

Controller示例如下:

@ExceptionHandler(value = { NullPointerException.class, ArrayIndexOutOfBoundsException.class })

public String exceptionExecute(Exception ex, HttpServletRequest request) {

    request.setAttribute("ex", ex);

    if (ex instanceof NullPointerException) {

         // 这里就写如何处理,比如:记日志

         System.out.println("now is NullPointer2");

         return "error/nullPage2";

    } else if (ex instanceof ArrayIndexOutOfBoundsException) {

         // 这里就写如何处理,比如:记日志

    }

    return "error/nullPage2";

}

三种处理方式都有的运行顺序

1:优先在自己Controller里面寻找@ExceptionHandler,看能不能处理

2:如果不能,然后在Spring中,寻找实现HandlerExceptionResolver 的Bean

3:对于多个都能处理的Bean,则按照配置的先后顺序进行处理

4:只要有一个能处理,不返回null,那么就结束

原文地址:https://www.cnblogs.com/zhouyeqin/p/9008387.html

时间: 2024-10-17 04:32:29

06数据验证的相关文章

Knockout.js 数据验证之插件版和无插件版

本文我们将介绍使用 Knockout.js 实现一些基本的数据验证.就如我们在标题里提到的,我们会使用两种方法来创建数据验证方法. 使用自定义方法,不需要任何插件 最简单的方法是使用已有的插件 如果你刚刚接触 Knockout.js,强烈建议你阅读我之前的 文章,那篇文章中我分享了一些关于 Knockout.js 的基本知识.本文我们使用 Visual Studio 进行开发,希望你能喜欢.现在开始. 源码下载 Knockout.js Validations 第 1 段(可获 1.23 积分)

POI 数据验证

从3.8开始,POI使用.xls和.xlsx格式处理数据校验略有不同之处.1)针对一个或多个预定义值检查用户输入到单元格的值以下代码将限制用户能输入到单元格A1的值是三个整数值(10.20.30)之一:    Workbook workbook = new XSSFWorkbook();  // 或者new HSSFWorkbook    Sheet sheet = workbook.createSheet("Data Validation");    // 数据验证帮助类    Da

strut2 的数据验证

数据验证 用户的输入验证,必须做,且工作量巨大. 1.验证的方式 客户端验证:javascript 服务端验证:逻辑验证(我们的代码) 注意:如果客户端和服务端二选一的话,服务器端的不能省. 实际开发中:客户端+服务端 2.Struts2的服务端验证 2.1.编程式验证 前提:                                    动作类必须继承ActionSupport                             在代码中编写验证规则. a.针对动作类中的所有动作方

我这么玩Web Api(二):数据验证,全局数据验证与单元测试

目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试   一.模型状态 - ModelState 我理解的ModelState是微软在ASP.NET MVC中提出的一种新机制,它主要实现以下几个功能: 1. 保存客户端传过来的数据,如果验证不通过,把数据返回到客户端,这样可以保存用户输入,不需要重新输入. 2. 验证数据,以及保存数据对应的错误信息. 3. 微软的一种DRY(Don't Repeat

数据验证【web前端,表单】

数据验证 最近做后台比较多,路七八糟的数据验证,弄得不厌其烦.SO,弄了个表单验证的玩意出来,达到快速,简介,不烦人的验证. 下面看看,几种方式的数据验证,有什么不同.先有需要验证的数据: <form> <input type="text" name="name" /> <input type="text" name="password" /> <input type="nu

如何使用JavaScript和正则表达式进行数据验证

利用客户端JavaScript的优势,JavaScript中的正则表达式可以简化数据验证的工作,下面与大家分享下如何使用JavaScript和正则表达式进行数据验证,感兴趣的朋友可以参考下哈 数据验证是网络应用软件从客户端接受数据的重要步骤,毕竟,您需要在使用客户数据前确保其符合预期的格式.在网络应用程序中,您可以选择使用特定平台的工具,比如ASP.NET.JSP等等,或者您可以利用客户端JavaScript的优势,JavaScript中的正则表达式可以简化数据验证的工作. 正则表达式 正则表达

MVC 数据验证

前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解.System.ComponentModel.DataAnnotations 一.基础特性 一.Required 必填选项,当提交的表单缺少该值就引发验证错误. 二.StringLength 指定允许的长度 指定最大长度: [StringLength(20)] //最大长度不超过20个字符 指定最短于最长限制: [StringLength(20,MinimumLength=3)] //最大长度不超过20个字符,最短不能低于3个字符

MVC 3 数据验证 Model Validation 详解

续我们前面所说的知识点进行下一个知识点的分析,这一次我们来说明一下数据验证.其实这是个很容易理解并掌握的地方,但是这会浪费大家狠多的时间,所以我来总结整理一下,节约一下大家宝贵的时间. 在MVC 3中 数据验证,已经应用的非常普遍,我们在web form时代需要在View端通过js来验证每个需要验证的控件值,并且这种验证的可用性很低.但是来到了MVC 新时代,我们可以通过MVC提供的数据验证Attribute来进行我们的数据验证.并且MVC 提供了客户端和服务器端 双层的验证,只有我们禁用了客户

MVC4 数据验证、特性、自动属性总结

最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精    最近在做自学MVC,遇到的问题很多,索性一点点总结下. MVC4数据验证: 本例以程序为例就行说明: public class MyModel { [Required(ErrorMessage = "请输入收件人姓名")] public string Uname { get; set; } [Required(ErrorMessage =