SpringMVC-表单验证
2016-06-05 00:50
447 查看
1.mvc:annotation-driven
实际开发时建议都配置该参数。配置<mvc:annotation-driven/>后,SpringMVC会自动注册RequestMappingHandlerMapping,
RequestMappingHandlerAdapter,ExceptionHandlerExceptionResolver三个bean。
还将提供一下支持
-支持用ConversionServices实例对表单参数进行类型转换,通过配置conversion-service属性自定义类型转换。
-支持使用@NumberFormat注解,@DateTimeFormat注解完成数据类型格式化
-支持使用@Valid注解对JavaBean实例进行JSR303验证
-支持使用@ReqeustBody和@ResponseBody注解
2.InitBinder注解
WebDataBinder用于完成表单字段到JavaBean属性的绑定,而@InitBinder注解则可以对WebDataBinder对象进行初始化,以及数据设定的相关限制。被InitBinder注解修饰的方法不能有返回值,且参数通常为WebDataBinder。
如下例子,规定name属性不会被表单字段自动绑定。
package spring; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class TestController { @RequestMapping(value="/test", method=RequestMethod.GET) public String testGet(Map<String, Object>map){ Person person = new Person(); map.put("person", person); return "form"; } @RequestMapping(value="/test", method=RequestMethod.POST) public String testPost(Person person){ System.out.println(person); return "success"; } @InitBinder public void testBinder(WebDataBinder dataBinder){ dataBinder.setDisallowedFields("name"); } }
3.数据格式化
表单的数据转换是将字符串形式的表单数据转换为JavaBean对象,如果是简单的对象不需要格式,则不需要特殊指定,但是比如日期类型的格式,如果不指定,则无法进行格式化,因为不知道是2016/6/4格式,还是2016-6-4格式。为了让SpringMVC在进行格式化时知道具体的目标,只需要在JavaBean对象中使用合适的注解进行类型,格式化标注即可。注解类型有:
-@NumberFormat
有两个互斥的属性,style:Style.NUMBER 正常数字,Style.PERCENT 百分数,Style.CURRENCY 货币
pattern:类型为String,可以进行自定义样式比如“#,###”
-@DateTimeFormat 可以对Date,Calendar,Long时间类型进行标注,有一个pattern属性,可以赋值比如“yyyy-MM-dd hh:mm:ss"的格式。
public class Person { @NumberFormat(pattern="##,##") //注意.是小数的关键字,不能用.分割。 private Integer id; @DateTimeFormat(pattern="YYYY-mm-dd") private Date birth;
4.数据校验
使用JSR303进行校验,JSR303是Java为Bean数据合法性校验提供的标准框架,在JavaEE6.0中已经实现。通过在JavaBean属性上加上注解,即可为属性提供校验功能。注解有如下内容
@Null 必须为空
@NotNull 必须非空
@AssertTrue 必须为True
@AssertFalse 必须为False
@Min(value) @Max(value) 这两个注解的属性必须是数字,且大于等于最小,小于等于最大
@DecimalMin(value) @DecimalMax(value) 同上
@Size(max,min)被注解的属性必须在之间。
@Digits(Integer, fraction) 注解的属性为数字,且在可接受范围内
@Past被注解的属性必须是过去时间,比如生日
@Future 必须是以后的时间。
@Pattern(value) 必须是符合指定的正则表达式
HibernateValidator的实现中,在JSR303基础上还提供了下面的几个注解:
@Email 有效的Email
@Length 字符串必须在指定的长度内
@NotEmpty 非空
@Range 元素必须在有效范围内。
5.配置数据校验步骤
1)SpringMVC的配置文件中需要加入<mvc:annotation-driven/>配置,这个配置用来装配LocalValidatorFactoryBean。2)由于Spring中没有实现JSR303,所以需要加入其他实现的jar包
hibernate-validator-5.2.4.Final.jar
hibernate-validator-annotation-processor-5.2.4.Final.jar
hibernate-validator-cdi-5.2.4.Final.jar
lib/required/validation-api-1.1.0.Final.jar
lib/required/jboss-logging-3.2.1.Final.jar
lib/required/classmate-1.1.0.jar
3)在Person Bean的name属性上添加@NotEmpty注解
4)在RequestMapping注解的方法参数上添加@Valid注解。
public String testValidator(@Valid Person person)
5)注意下面例子中,参数①要验证的person,②验证结果personValidateResult之间不能有其他参数。
@RequestMapping(value="/test", method=RequestMethod.POST) public String testValidate(@Valid Person person, /*BindingResult error,*/ BindingResult personValidateResult){ if(personValidateResult.getErrorCount() > 0){ System.out.println("Error"); for(FieldError fieldError:personValidateResult.getFieldErrors()){ System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage()); return "form"; } }else{ System.out.println(person); } return "success"; }
6.在页面上回显错误信息
只需要使用<form:errors path="指定属性的错误信息">即可在网页中回显。7.定制错误信息
每个属性的数据绑定和数据校验发生错误时,都会生成一个对应的FieldError对象。当一个属性校验失败后,校验框架会为该属性生成四个错误消息代码。注解前缀,ModelAttribute,属性名即属性类型名:以Person类中name属性标注了@Pattern注解为例,会生成一下四个错误代码
-Pattern.person.name //注意person是Person类定义的实际变量参数的名字
-Pattern.name
-Pattern.java.lang.String
-Pattern
当使用SpringMVC进行错误显示时,会查看WEB上下文是否制定了国际化配置,有则用,无则显示默认值。
另外三个特殊的信息:
-@RequiredParam() 参数不存在的错误,用required.前缀
-数据绑定类型错误时,typeMismatch前缀
-methodInvocation:SpringMVC在调用处理方法时发生错误
完整的代码清单如下:
1.Person Bean的定义
package spring; import java.util.Date; import javax.validation.constraints.Past; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.NumberFormat; public class Person { @NumberFormat(pattern="##,##") //注意.是小数的关键字,不能用.分割。 private Integer id; @Past //表单校验,生日必须发生在今天以前 @DateTimeFormat(pattern="YYYY-mm-dd") //数据格式化 private Date birth; @NotEmpty //表单校验,名字不能为空 private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Person(Integer id, String name, Date birth) { super(); this.id = id; this.name = name; this.birth = birth; } public Person(){} @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", birth=" + birth + "]"; } }2.配置文件
<?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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="spring"></context:component-scan> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"></property> <property name="suffix" value=".jsp"></property> </bean> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="i18n"></property> </bean> <mvc:default-servlet-handler/> <mvc:annotation-driven></mvc:annotation-driven> </beans>3.i18n.properties
在配置文件中指定了basename为i18n,则必须定义i18n.properties的配置文件。由于是UTF-8的,汉字都会被转码
NotEmpty.person.name=\u4EBA\u7684\u540D\u5B57\u4E0D\u80FD\u4E3A\u7A7A //<span style="color:red;">人的名字不能为空</span>
Past.person.birth=\u51FA\u751F\u65E5\u671F\u6709\u95EE\u9898 //<span style="color: red; font-family: Arial, Helvetica, sans-serif; font-size: 12px;">出生日期有问题</span>4.index.jsp
<body> <a href="/spring/test">Add New</a> </body>5.form.jsp
用<form:xxx>定义表单成员时,必须配置modelAttribute,或者使用默认的command。为了获取这个数据,必须先经过下面@RequestMapping中先设置command,或者modelAttribute的数据,然后经过转发跳转到该页面。
form:errors用来回显错误信息。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import="java.util.Map,java.util.HashMap" %> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form:form method="POST" action="/spring/test" modelAttribute="person"> ID:<form:input path="id"/><font color="red"><form:errors path="id"/></font><br> Name:<form:input path="name"/><font color="red"><form:errors path="name"/></font><br> birth:<form:input path="birth"/><font color="red"><form:errors path="birth"/></font><br> <input type="submit" value="submit"> </form:form> </body> </html>6.控制器代码
package spring; import java.util.Map; import javax.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class TestController { @RequestMapping(value="/test", method=RequestMethod.GET) public String testGet(Map<String, Object>map){ Person person = new Person(); map.put("person", person); return "form"; } @RequestMapping(value="/test", method=RequestMethod.POST) public String testValidate(@Valid Person person, /*BindingResult error,*/ BindingResult personValidateResult){ if(personValidateResult.getErrorCount() > 0){ System.out.println("Error"); for(FieldError fieldError:personValidateResult.getFieldErrors()){ System.out.println(fieldError.getField() + ":" + fieldError.getDefaultMessage()); return "form"; } }else{ System.out.println(person); } return "success"; } }<完>
相关文章推荐
- 新建maven项目pom报错
- Struts2系列入门教程---第一章 HelloStruts2
- eclipse中安装maven插件及创建maven项目
- 【GOF23设计模式】_代理模式_静态代理_动态代理_开发场景JAVA236-237
- 分布式锁1 Java常用技术方案
- org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'loginAction‘
- SpringMvc入门四----rest风格Url
- 关于java动态代理模式
- Maven Myeclipse classes下加载不到静态文件解决办法
- java数据类型转换
- spring、mybatis 配置方式详解(常用两种方式)
- springmvc与mybatis整合配置
- Java 中byte 与 char 的相互转换
- Code Hunt Sector 10 Jagged Arrays - Java
- Code Hunt Sector 11 Arrays 2 - Java
- Code Hunt Sector 12 Search Sort - Java
- Code Hunt Sector 13 Cyphers - Java
- Code Hunt Sector 14 Puzzles - Java
- Leet Code 1 Two Sum - 查找数组中和等于给定值的两个数 - Java
- Leet Code 2 Add Two Numbers - 链表表示的两个数求和 - Java