zoukankan      html  css  js  c++  java
  • SpringMVC数据验证

    SpringMVC学习系列(6) 之 数据验证

    在系列(4)、(5)中我们展示了如何绑定数据,绑定完数据之后如何确保我们得到的数据的正确性?这就是我们本篇要说的内容 —> 数据验证。

    这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证。首先我们要到http://hibernate.org/validator/下载需要的jar包,这里以4.3.1.Final作为演示,解压后把hibernate-validator-4.3.1.Final.jar、jboss-logging-3.1.0.jar、validation-api-1.0.0.GA.jar这三个包添加到项目中。

    配置之前项目中的springservlet-config.xml文件,如下:

    复制代码
    <!-- 默认的注解映射的支持 -->  
        <mvc:annotation-driven validator="validator" conversion-service="conversion-service" />
        
        <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
            <property name="providerClass"  value="org.hibernate.validator.HibernateValidator"/>
            <!--不设置则默认为classpath下的 ValidationMessages.properties -->
            <property name="validationMessageSource" ref="validatemessageSource"/>
        </bean>
        <bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
        <bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
            <property name="basename" value="classpath:validatemessages"/>  
            <property name="fileEncodings" value="utf-8"/>  
            <property name="cacheSeconds" value="120"/>  
        </bean>
    复制代码

    其中<property name="basename" value="classpath:validatemessages"/>中的classpath:validatemessages为注解验证消息所在的文件,需要我们在resources文件夹下添加。

    在com.demo.web.controllers包中添加一个ValidateController.java内容如下:

    复制代码
    package com.demo.web.controllers;
    
    import java.security.NoSuchAlgorithmException;
    import javax.validation.Valid;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import com.demo.web.models.ValidateModel;
    
    @Controller
    @RequestMapping(value = "/validate")
    public class ValidateController {
        
        @RequestMapping(value="/test", method = {RequestMethod.GET})
        public String test(Model model){
    
            if(!model.containsAttribute("contentModel")){
                model.addAttribute("contentModel", new ValidateModel());
            }
            return "validatetest";
        }
        
        @RequestMapping(value="/test", method = {RequestMethod.POST})
        public String test(Model model, @Valid @ModelAttribute("contentModel") ValidateModel validateModel, BindingResult result) throws NoSuchAlgorithmException{
            
            //如果有验证错误 返回到form页面
            if(result.hasErrors())
                return test(model);
            return "validatesuccess";     
        }
        
    }
    复制代码

    其中@Valid @ModelAttribute("contentModel") ValidateModel validateModel的@Valid 意思是在把数据绑定到@ModelAttribute("contentModel") 后就进行验证。

    在com.demo.web.models包中添加一个ValidateModel.java内容如下:

    复制代码
    package com.demo.web.models;
    
    import org.hibernate.validator.constraints.Email;
    import org.hibernate.validator.constraints.NotEmpty;
    import org.hibernate.validator.constraints.Range;
    
    public class ValidateModel{
        
        @NotEmpty(message="{name.not.empty}")
        private String name;
        @Range(min=0, max=150,message="{age.not.inrange}")
        private String age;
        @NotEmpty(message="{email.not.empty}")
        @Email(message="{email.not.correct}")
        private String email;
        
        public void setName(String name){
            this.name=name;
        }
        public void setAge(String age){
            this.age=age;
        }
        public void setEmail(String email){
            this.email=email;
        }
        
        public String getName(){
            return this.name;
        }
        public String getAge(){
            return this.age;
        }
        public String getEmail(){
            return this.email;
        }
        
    }
    复制代码

    在注解验证消息所在的文件即validatemessages.properties文件中添加以下内容:

    name.not.empty=u540Du79F0u4E0Du80FDu4E3Au7A7Au3002
    age.not.inrange=u5E74u9F84u8D85u51FAu8303u56F4u3002
    email.not.correct=u90AEu7BB1u5730u5740u4E0Du6B63u786Eu3002
    email.not.empty=u7535u5B50u90AEu4EF6u4E0Du80FDu60DFu6050u3002

    其中name.not.empty等分别对应了ValidateModel.java文件中message=”xxx”中的xxx名称,后面的内容是在输入中文是自动转换的ASCII编码,当然你也可以直接把xxx写成提示内容,而不用另建一个validatemessages.properties文件再添加,但这是不正确的做法,因为这样硬编码的话就没有办法进行国际化了。

    在views文件夹中添加validatetest.jsp和validatesuccess.jsp两个视图,内容分别如下:

    复制代码
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    
    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
    
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <form:form modelAttribute="contentModel" method="post">     
            
            <form:errors path="*"></form:errors><br/><br/>
                
            name:<form:input path="name" /><br/>
            <form:errors path="name"></form:errors><br/>
            
            age:<form:input path="age" /><br/>
            <form:errors path="age"></form:errors><br/>
            
            email:<form:input path="email" /><br/>
            <form:errors path="email"></form:errors><br/>
    
            <input type="submit" value="Submit" />
            
        </form:form>  
    </body>
    </html>
    复制代码
    复制代码
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!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>
        验证成功!
    </body>
    </html>
    复制代码

    其中特别要指出的是validatetest.jsp视图中<form:form modelAttribute="contentModel" method="post">modelAttribute="xxx"后面的名称xxx必须与对应的@Valid @ModelAttribute("xxx") 中的xxx名称一致,否则模型数据和错误信息都绑定不到。

    <form:errors path="name"></form:errors>即会显示模型对应属性的错误信息,当path="*"时则显示模型全部属性的错误信息。

    运行测试:

    1

    直接点击提交:

    2

    可以看到正确显示了设置的错误信息。

    填写错误数据提交:

    3

    可以看到依然正确显示了设置的错误信息。

    填写正确数据提交:

    4

    5

    可以看到验证成功。

    下面是主要的验证注解及说明:

    注解

    适用的数据类型

    说明

    @AssertFalse

    Boolean, boolean

    验证注解的元素值是false

    @AssertTrue

    Boolean, boolean

    验证注解的元素值是true

    @DecimalMax(value=x)

    BigDecimal, BigInteger, String, byte,short, int, long and the respective wrappers of the primitive types. Additionally supported by HV: any sub-type of Number andCharSequence.

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

    @DecimalMin(value=x)

    BigDecimal, BigInteger, String, byte,short, int, long and the respective wrappers of the primitive types. Additionally supported by HV: any sub-type of Number andCharSequence.

    验证注解的元素值小于等于@ DecimalMin指定的value值

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

    BigDecimal, BigInteger, String, byte,short, int, long and the respective wrappers of the primitive types. Additionally supported by HV: any sub-type of Number andCharSequence.

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

    @Future

    java.util.Date, java.util.Calendar; Additionally supported by HV, if theJoda Time date/time API is on the class path: any implementations ofReadablePartial andReadableInstant.

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

    @Max(value=x)

    BigDecimal, BigInteger, byte, short,int, long and the respective wrappers of the primitive types. Additionally supported by HV: any sub-type ofCharSequence (the numeric value represented by the character sequence is evaluated), any sub-type of Number.

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

    @Min(value=x)

    BigDecimal, BigInteger, byte, short,int, long and the respective wrappers of the primitive types. Additionally supported by HV: any sub-type of CharSequence (the numeric value represented by the char sequence is evaluated), any sub-type of Number.

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

    @NotNull

    Any type

    验证注解的元素值不是null

    @Null

    Any type

    验证注解的元素值是null

    @Past

    java.util.Date, java.util.Calendar; Additionally supported by HV, if theJoda Time date/time API is on the class path: any implementations ofReadablePartial andReadableInstant.

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

    @Pattern(regex=正则表达式, flag=)

    String. Additionally supported by HV: any sub-type of CharSequence.

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

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

    String, Collection, Map and arrays. Additionally supported by HV: any sub-type of CharSequence.

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

    @Valid

    Any non-primitive type(引用类型)

    验证关联的对象,如账户对象里有一个订单对象,指定验证订单对象

    @NotEmpty

    CharSequence,CollectionMap and Arrays

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

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

    CharSequence, Collection, Map and Arrays,BigDecimal, BigInteger, CharSequence, byte, short, int, long and the respective wrappers of the primitive types

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

    @NotBlank

    CharSequence

    验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格

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

    CharSequence

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

    @Email

    CharSequence

    验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

    更多信息请参考官方文档:http://docs.jboss.org/hibernate/validator/4.3/reference/en-US/html/validator-usingvalidator.html

    数据验证的内容到此结束,代码下载:http://pan.baidu.com/s/1pJDc12V

     
     
    分类: Spring MVC
    标签: SpringMVC
  • 相关阅读:
    118/119. Pascal's Triangle/II
    160. Intersection of Two Linked Lists
    168. Excel Sheet Column Title
    167. Two Sum II
    172. Factorial Trailing Zeroes
    169. Majority Element
    189. Rotate Array
    202. Happy Number
    204. Count Primes
    MVC之Model元数据
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3746943.html
Copyright © 2011-2022 走看看