(笔记)Spring MVC学习指南_验证器

本文介绍了SpringMVC中的两种验证方法:使用Spring自带的验证框架和利用JSR303标准进行验证。详细讨论了验证器的实现方式、常用工具类ValidationUtils的使用方法以及JSR303的具体应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Spring MVC中,有两种方式可以验证输入,即利用Spring自带的验证框架,或者利用JSR 303实现。
1.验证概览
Converter和Formatter作用于field级。在MVC应用程序中,它们将String转换或格式化成另一种Java类型。验证器则作用于object级。它决定某一个对象中的所有field是否均是有效的,以及是否遵循某些规则。
如果一个应用程序中即使用了Formatter,又有validator(验证器),那么,它们的事件顺序是这样的:在调用Controller期间,将会有一个或者多个Formatter,试图将输入字符串转换成domain对象中的field值。一旦格式化成功,验证器就会介入。
2.Spring验证器
为了创建Spring验证器,要实现org.springframework.validation.Validator接口。

package org.springframework.validation;
public interface Validator {
    boolean supports(Class<?> clazz);
    void validate(Object target, Errors errors);
}

如果验证器可以处理指定的Class,supports方法将返回true。validate方法会验证目标对象,并将验证错误填入Errors对象。
Errors对象是org.springframework.validation.Errors接口的一个实例。Errors对象中包含了一系列FieldError和ObjectError对象。FieldError表示与被验证对象中的某个属性相关的一个错误。
编写验证器时,不需要直接创建Error对象,因为实例化ObjectError或FieldError花费了大量的编程精力。给Errors对象添加错误的最容易的方法是:在Errors对象上调用一个reject或者rejectValue方法。

void reject(String errorCode)
void reject(String errorCode, String defaultMessage)
void rejectValue(String field, String errorCode)
void rejectValue(String field, String errorCode, String defaultMessage)

大多数时候,只给reject或者rejectValue方法传入一个错误码,Spring就会在属性文件中查找错误码,获得相应的错误消息。还可以传入一个默认消息,当没有找到指定的错误码时,就会使用默认消息。
Errors对象中的错误消息,可以利用表单标签库的Errors标签显示在HTML页面中。
3.ValidationUtils类
org.springframework.validation.ValidationUtils类是一个工具,有助于编写Spirng验证器。
4.Spring的Validator范例

package app07a.validator;


import java.util.Date;

import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;

import app07a.domain.Product;


public class ProductValidator implements Validator
{

    @Override
    public boolean supports(Class<?> clazz)
    {
        return Product.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object target, Errors errors)
    {
        Product product = (Product)target;
        ValidationUtils.rejectIfEmpty(errors, "name", "productname.required");
        ValidationUtils.rejectIfEmpty(errors, "price", "price.required");
        ValidationUtils.rejectIfEmpty(errors, "productionDate", "productiondate.required");
        Float price = product.getPrice();
        if (price != null && price < 0)
        {
            errors.rejectValue("price", "price.negative");
        }
        Date productionDate = product.getProductionDate();
        if (productionDate != null)
        {
            if (productionDate.after(new Date()))
            {
                errors.rejectValue("productionDate", "productiondate.invalid");
            }
        }
    }

}

验证器不需要显式注册,但是如果想要从某个属性文件中获取错误信息,则需要通过声明messageSource bean,告诉Spring要去哪里查找这个文件。

    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="/WEB-INF/resource/messages" />
    </bean>

messages.properties

productname.required=Please enter a product name
price.required=Please enter a price
productiondate.required=Please enter a production date
price.negative=Invalid price.Please enter a price greater than zero
productiondate.invalid=Invalid production date.Please ensure the production date is not later than today

使用Spring验证器的另一种方法是:在Controller中编写initBinder方法,并将验证器传到WebDataBinder,并调用其validate方法。

    @org.springframework.web.bind.annotation.InitBinder
    public void InitBinder(WebDataBinder binder)
    {
        binder.setValidator(new ProductValidator());
        binder.validate();
    }

8.JSR 303验证
对于JSR bean validation,目前有两个实现。第一个实现时Hibernate Validator,第二个实现时Apache BVal。
JSR 303不需要编写验证器,但要利用JSR 303标注类型嵌入约束。

属性描述
@AssertFalse应用于boolean属性,该属性值必须为False
@AssertTrue应用于boolean属性,该属性值必须为True
@DecimalMax该属性值必须为小于或等于指定值的小数
@DecimalMin该属性值必须为大于或等于指定值的小数
@Digits该属性值必须在指定范围内。integer属性定义该数值的最大整数部分,fraction属性定义该数值的最大小数部分
@Future该属性值必须是一个未来的日期
@Max该属性值必须是一个小于或等于指定值的整数
@Min该属性值必须是一个大于或等于指定值的整数
@NotNull该属性值不能为Null
@Null该属性值必须为Null
@Past该属性值必须是过去的一个日期
@Pattern该属性值必须与指定的常规表达式相匹配
@Size该属性值必须在指定范围内

9.JSR 303 Validator范例
jar包
需要导入jar包

    <mvc:annotation-driven validator="validator" />

    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
        <property name="validationMessageSource" ref="messageSource" />
    </bean>
    <bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basename" value="/WEB-INF/resource/messages" />
    </bean>
@RequestMapping(value = "/product_save")
    public String saveProduct(@Valid @ModelAttribute Product product, BindingResult bindingResult,
                              Model model)
package app07b.domain;


import java.io.Serializable;
import java.util.Date;

import javax.validation.constraints.Past;
import javax.validation.constraints.Size;

import com.sun.istack.internal.NotNull;


public class Product implements Serializable
{

    private static final long serialVersionUID = -164834188493691288L;

    @Size(min = 1, max = 10)
    private String name;

    @NotNull
    private String description;

    private Float price;

    @Past
    private Date productionDate;

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getDescription()
    {
        return description;
    }

    public void setDescription(String description)
    {
        this.description = description;
    }

    public Float getPrice()
    {
        return price;
    }

    public void setPrice(Float price)
    {
        this.price = price;
    }

    public Date getProductionDate()
    {
        return productionDate;
    }

    public void setProductionDate(Date productionDate)
    {
        this.productionDate = productionDate;
    }

}

由于JSR 303是正式的Java规范,因此新项目建议使用JSR 303验证器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值