您的位置:首页 > 编程语言 > Java开发

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";
}
}
<完>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: