SpringMVC 使用JSR-303进行校验 @Valid

使用注解

一、准备校验时使用的JAR

validation-api-1.0.0.GA.jar:JDK的接口;

hibernate-validator-4.2.0.Final.jar是对上述接口的实现;

log4j、slf4j、slf4j-log4j

        <dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>

http://hibernate.org/validator/documentation/getting-started/

	... 128 common frames omitted
Caused by: javax.validation.ValidationException: HV000183: Unable to load 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath
at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.<init>(ResourceBundleMessageInterpolator.java:172) ~[hibernate-validator-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.<init>(ResourceBundleMessageInterpolator.java:118) ~[hibernate-validator-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:110) ~[hibernate-validator-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.validator.internal.engine.ConfigurationImpl.<init>(ConfigurationImpl.java:86) ~[hibernate-validator-5.1.0.Final.jar:5.1.0.Final]
at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:41) ~[hibernate-validator-5.1.0.Final.jar:5.1.0.Final]
at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:276) ~[validation-api-1.1.0.Final.jar:na]
... 137 common frames omitted

http://www.tuicool.com/articles/eQf2Ejv

http://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/http-entity/

二、编写需要校验的bean

@NotNull(message="名字不能为空")
private String userName;
@Max(value=120,message="年龄最大不能查过120")
private int age;
@Email(message="邮箱格式错误")
private String email;

三、校验方法

@RequestMapping("/login")
public String testValid(@Valid User user, BindingResult result){
if (result.hasErrors()){
List<ObjectError> errorList = result.getAllErrors();
for(ObjectError error : errorList){
System.out.println(error.getDefaultMessage());
}
} return "test";
}

备注:这里一个@Valid的参数后必须紧挨着一个BindingResult 参数,否则spring会在校验不通过时直接抛出异常

前台可以使用spring的标签库也可以自己自定义处理

spring标签库的用法:

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

<html>
<head>
<title>Reservation Form</title>
<style>
.error {
color: #ff0000;
font-weight: bold;
}
</style>
</head> <body>
<form:form method="post" modelAttribute="vm">
<form:errors path="*" cssClass="error" />
<table>
<tr>
<td>Name</td>
<td><form:input path="userName" />
</td>
<td><form:errors path="userName" cssClass="error" />
</td>
</tr>
<tr>
<td>email</td>
<td><form:input path="email" />
</td>
<td><form:errors path="email" cssClass="error" />
</td>
</tr> <tr>
<td colspan="3"><input type="submit" />
</td>
</tr>
</table>
</form:form>
</body>
</html>

四、开启spring的Valid功能

<mvc:annotation-driven />

五、JSR303定义的校验类型

空检查

@Null 验证对象是否为null

@NotNull 验证对象是否不为null, 无法查检长度为0的字符串

@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.

@NotEmpty 检查约束元素是否为NULL或者是EMPTY.

Booelan检查

@AssertTrue 验证 Boolean 对象是否为 true

@AssertFalse 验证 Boolean 对象是否为 false

长度检查

@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内

@Length(min=, max=) Validates that the annotated string is between min and max included.

日期检查

@Past 验证 Date 和 Calendar 对象是否在当前时间之前

@Future 验证 Date 和 Calendar 对象是否在当前时间之后

@Pattern 验证 String 对象是否符合正则表达式的规则

数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null

@Min 验证 Number 和 String 对象是否大等于指定的值

@Max 验证 Number 和 String 对象是否小等于指定的值

@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度

@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度

@Digits 验证 Number 和 String 的构成是否合法

@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。

@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.

@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;

@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)

@CreditCardNumber信用卡验证

@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。

@ScriptAssert(lang= ,script=, alias=)

@URL(protocol=,host=, port=,regexp=, flags=)

6、自定义校验类型

可以参考:http://exceptioneye.iteye.com/blog/1305040

使用接口

可以参考:http://elf8848.iteye.com/blog/1299587

http://www.cnblogs.com/yangzhilong/p/3724967.html

 
    @RequestMapping("/add2")
public String addStudentValid(@Valid @ModelAttribute("s") Student s,BindingResult result){
if(result.hasErrors()){
List<FieldError> fieldErrors = result.getFieldErrors(); for (FieldError fieldError : fieldErrors) {
log.info("errors --"+fieldError.getField()+fieldError.getDefaultMessage());
}
}
log.info("s.name="+s.getName());
log.info("s.age="+s.getAge());
return "success";
}
import javax.validation.constraints.Min;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty; public class Student { @NotEmpty
@Length(min=4,message="{stu.name}")
private String name;
@Min(value=18,message="{stu.age}")
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "toString - name="+name+";age="+age;
} }

需要开启注解 <mvc:annotation-driven/>才能启用验证。否则@valid不管用。

如果要使用错误提示的国际化消息,如stu.name为properties文件中的键值对
@Length(min=4,message="{stu.name}")

则需要在dispatcher-servlet.xml中配置

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:validmessages"/>
<property name="fileEncodings" value="utf-8"/>
<property name="cacheSeconds" value="120"/>
</bean> <!-- 以下 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> <mvc:annotation-driven validator="validator"/>

在src/main/resources下放入validmessages.properties即可。

上面的配置设置了自定义validator,使用messageSource为错误消息提示资源文件。

validmessages.properties内容为

stu.name=\u540D\u79F0\u7684\u957F\u5EA6\u4E0D\u80FD\u5C0F\u4E8E{min}\u554A!
stu.age=\u5E74\u9F84\u5FC5\u987B\u5927\u4E8E{value}\u5C81\u554A!

可以通过{value} {min} {max}等引用注解里的值。

当名称长度小于4 age小于18 输出:

名称的长度不能小于4啊!
age年龄必须大于18岁啊!

本次测试的dispatcher-servlet.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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
"> <context:component-scan base-package="com.upper"/> <!-- freemarker的配置 -->
<bean id="freemarkerConfigurer"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/views/" />
<property name="defaultEncoding" value="GBK" />
<property name="freemarkerSettings">
<props>
<prop key="template_update_delay">0</prop>
<prop key="locale">zh_CN</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="date_format">yyyy-MM-dd</prop>
<prop key="number_format">#.##</prop>
<!-- <prop key="auto_import">c_index.tpl as p</prop> -->
</props>
</property>
</bean>
<!-- FreeMarker视图解析 如返回userinfo。。在这里配置后缀名ftl和视图解析器。。 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=GBK" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
<property name="requestContextAttribute" value="rc" />
<property name="allowSessionOverride" value="true"/>
</bean> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:validmessages"/>
<property name="fileEncodings" value="utf-8"/>
<property name="cacheSeconds" value="120"/>
</bean> <!-- 以下 validator ConversionService 在使用 mvc:annotation-driven 会 自动注册-->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<!-- 如果不加默认到 使用classpath下的 ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource" />
</bean> <mvc:annotation-driven validator="validator"/>
</beans>

http://www.cnblogs.com/beenupper/p/3395872.html

对于后端的参数校验,我们一直在强调的验证规则,提示信息的重用。这不,springmvc通过集成Valid最大程序减少了我们的工作量。其实后端的参数过滤,是分几种请求来源的。每种的处理都不太一样,但是我们如果能重用验证规则,提示信息,那就很强大了。
1 常用的表单提交,需要页面返回错误信息
2 AJAX提交,需要JSON格式返回,或者XML
3 接口调用,同样需要对应的数据格式返回
对于这3类请求,我今天讲的是第3种,是可以重用第1种的资源和验证规则。
考虑通过AOP加注解,拦截方法中的BEAN,通过获取期验证返回信息,提前抛出验证异常。
 

里面的processValidationError方法会处理具体异常的返回值并以JSON输出,大功告成.
整体代码链接。
demo代码:https://github.com/igool/validatedemo
子模块:https://github.com/igool/lombakcode

当这样处理之后,我们的resetful的接口只用处理真正的业务,完全不用做常用的参数检查。

http://www.blogjava.net/zuxiong/archive/2015/11/27/428389.html

@Valid springMVC bean校验不起作用及如何统一处理校验的更多相关文章

  1. @Valid springMVC bean校验不起作用

    @RequestMapping("/add2") public String addStudentValid(@Valid @ModelAttribute("s" ...

  2. SpringMVC参数校验,包括JavaBean和基本类型的校验

    该示例项目使用SpringBoot,添加web和aop依赖. SpringMVC最常用的校验是对一个javaBean的校验,默认使用hibernate-validator校验框架.而网上对校验单个参数 ...

  3. SpringMVC学习笔记六:使用 hibernate-validator注解式数据校验

    对客户端传过来的参数,在使用前一般需要进行校验. SpringMVC框架内置了Validator验证接口,但是实现起来太麻烦.我们一般使用 hibernate-validator进行数据校验. 1:j ...

  4. 关于 Spring Boot 中创建对象的疑虑 → @Bean 与 @Component 同时作用同一个类,会怎么样?

    开心一刻 今天放学回家,气愤愤地找到我妈 我:妈,我们班同学都说我五官长得特别平 妈:你小时候爱趴着睡觉 我:你怎么不把我翻过来呢 妈:那你不是凌晨2点时候出生的吗 我:嗯,凌晨2点出生就爱趴着睡觉呗 ...

  5. SpringBoot Validation参数校验 详解自定义注解规则和分组校验

    前言 Hibernate Validator 是 Bean Validation 的参考实现 .Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的 ...

  6. struts_20_对Action中所有方法、某一个方法进行输入校验(基于XML配置方式实现输入校验)

    第01步:导包 第02步:配置web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app ...

  7. Android5.1.1 - APK签名校验分析和修改源码绕过签名校验

    Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...

  8. MM--发票校验 及基于采购订单的MIRO发票校验过程(

    一.介绍发票校验是物料管理(MM)系统的一部分.它提供物料管理部分和财务会计, 成本控制和资产管理部分的连接.物料管理模块的发票校验为以下目的服务:它完成物料采购的全过程 - 物料采购从采购申请开始, ...

  9. struts系列:校验(一)XML校验和函数方法校验

    一.jsp示例 <form action="login" method="post"> <div class="form-group ...

随机推荐

  1. 细聊 Cocoapods 与 Xcode 工程配置

    前言 文章比较长,所以在文章的开头我打算简单介绍一下这篇文章将要讲述的内容,读者可以选择通篇细度,也可以直接找到自己感兴趣的部分. 既然是谈 Cocoapods,那首先要搞明白它出现的背景.有经验的开 ...

  2. Cocoa Touch 层

    Cocoa Touch层包含创建 iOS应用程序所需的关键框架.上至实现应用程序可视界面,下至与高级系统服务交互,都需要该层技术提供底层基础.在开发应用程序的时候,请尽可能不要使用更底层的框架,尽可能 ...

  3. ContentProvider简单介绍

    1.什么是ContentProvider  数据库在Android其中是私有的,当然这些数据包含文件数据和数据库数据以及一些其它类型的数据.  不能将数据库设为WORLD_READABLE,每一个数据 ...

  4. 安装android studio 出现的路径问题 tools.jar' seems to be not in Android Studio classpath

    尝试一下android studio  ,谁知出现路径问题 'tools.jar' seems to be not in Android Studio classpath. Please ensure ...

  5. html:标签原本属性

    <!doctype html>无标题文档 a标签,默认有text-decoration属性 span标签不需要清零 b标签不需要清零 em标签不需要清零 strong 相邻内嵌元素代码里面 ...

  6. .NET Reflector 8.3.3.115 官方最新版+注册机(强大的.NET反编译工具破解版)

    Lutz Roeder’s .NET Reflector,是一个可以将以.NET Framework为基础开发出来的的DLL或EXE文件,反编译为原始程序的工具软件..NET Reflector 工具 ...

  7. pod install后出现: [!] `<PBXResourcesBuildPhase UUID=`xxxx`>` attempted to initialize an object with an unknown UUID

    [!] `<PBXResourcesBuildPhase UUID=`xxx`>` attempted to initialize an object with an unknown UU ...

  8. php curl操作

    <?php // $curl=curl_init(); // $url="http://localhost/cc/get.php?lo=ccc"; // curl_setop ...

  9. Smtp协议与Pop3协议的简单实现

    前言 本文主要介绍smtp与pop3协议的原理,后面会附上对其的简单封装与实现. smtp协议对应的RFC文档为:RFC821 smtp协议 SMTP(Simple Mail Transfer Pro ...

  10. 工作流activiti-02事物控制、流程引擎创建

    使用activiti中有个很重要的问题就是需要保证事物的控制 activiti使用的是mybatis作为orm技术 封装了一系列的操作数据库操作  这也就是大家调用的api 操作的数据库表都是acti ...