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

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,那么就结束

06springMVC数据验证的更多相关文章

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

    目录 一.模型状态 - ModelState 二.数据注解 - Data Annotations 三.自定义数据注解 四.全局数据验证 五.单元测试   一.模型状态 - ModelState 我理解 ...

  2. MVC 数据验证

    MVC 数据验证 前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解.System.ComponentModel.DataAnnotations 一.基础特性 一.Required 必填 ...

  3. kpvalidate开辟验证组件,通用Java Web请求服务器端数据验证组件

    小菜利用工作之余编写了一款Java小插件,主要是用来验证Web请求的数据,是在服务器端进行验证,不是简单的浏览器端验证. 小菜编写的仅仅是一款非常初级的组件而已,但小菜为它写了详细的说明文档. 简单介 ...

  4. MVC3 数据验证用法之密码验证设计思路

    描述:MVC数据验证使用小结 内容:display,Required,stringLength,Remote,compare,RegularExpression 本人最近在公司用mvc做了一个修改密码 ...

  5. jQuery MiniUI开发系列之:数据验证

    在开发应用系统界面时,往往需要进行很多.复杂的数据验证,当填写的数据符合规定,才能提交保存. jQuery MiniUI提供了比较完美的表单数据验证和错误显示的方式. 常见的表单控件,都有一个验证事件 ...

  6. AngularJS快速入门指南14:数据验证

    thead>tr>th, table.reference>tbody>tr>th, table.reference>tfoot>tr>th, table ...

  7. atitit.数据验证--db数据库数据验证约束

    atitit.数据验证--db数据库数据验证约束 1. 为了加强账户数据金额的安全性,需要增加验证字段..1 2. 创建帐户1 3. 更改账户2 4. ---code3 5. --fini4 1. 为 ...

  8. MVC数据验证原理及自定义ModelValidatorProvider实现无编译修改验证规则和错误信息

    Asp.net MVC中的提供非常简单易用的数据验证解决方案. 通过System.ComponentModel.DataAnnotations提供的很多的验证规则(Required, StringLe ...

  9. MVC 数据验证[转]

    前一篇说了MVC数据验证的例子,这次来详细说说各种各样的验证注解. 一.基础特性 一.Required 必填选项,当提交的表单缺少该值就引发验证错误. 二.StringLength 指定允许的长度 指 ...

随机推荐

  1. SEL是啥玩意

    一.了解SEL前的准备-----isa指针简述 1.一个类就像一个 C 结构,NSObject 声明了一个成员变量: isa.由于 NSObject 是所有类的根类,所以所有的对象都会有一个 isa ...

  2. E20170629-hm

    enqueue  [计] 入队,排队; dequeue  [计]  出列; rear  n. 后部,背面,背后; 臀部; (舰队或军队的) 后方,后尾,殿后部队; 〈英口〉厕所; ring buffe ...

  3. HTML-ul分分钟理解

    在HTML中,列表有三种,如图分别是有序.无序和自定义列表.上面是我在网络上找到的一张图片很明了就看以看出来,今天要分享的就是其中的无序列表Ul(unordered list),给大家整理了一下我所知 ...

  4. websocket的原理

    首先明确几点: 1. websocket是一种协议.是html5的一种新协议: 2. 与http的区别是,它是一种双向通信协议,服务器和客户端都能主动向对方发送或接受数据: 3. websocket需 ...

  5. 【Leetcode 86】 Partition List

    问题描述: 给定一个list, 将所有小于x的node放到左边,剩下的保持原样. 问题解决: 闲的无聊,用c++和python都做了一遍. 代码如下: # Definition for singly- ...

  6. Laravel 5.4.36 session 生效问题

    在测试过程中发现 如果方法有echo 等函数输出到PHP的输出缓存中 存在  sessionID 不会放到http的请求头中  下次请求也就拿不到sessionid问题 问题的原因 代码位置:publ ...

  7. node.js安装步骤

    首先这是node.js的官网:https://nodejs.org/en/ 截至2017年12月9日,node更新在8.9.3该版本,建议开发人员下载6.0以上版本,8以上不是很稳定!  如果有其他需 ...

  8. ASP.NET MVC 二维码生成(ThoughtWorks.QRCode)

    原文地址http://www.cnblogs.com/jys509/p/4592539.html

  9. [Windows Server 2008] ASP.net安装方法

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装ASP.n ...

  10. Caffe FCN:可视化featureMaps和Weights(C++)、获取FCN结果

    为何不使用C++版本FCN获取最后的分割掩模,何必要使用python呢!因此需要获取网络最后层的featureMaps,featureMaps的结果直接对应了segmentation的最终结果,可以直 ...