java web 之springmvc教程(六)-----数据校验

本文介绍如何在SpringMVC中使用Hibernate Validator进行参数校验,包括校验配置、注解使用、错误信息捕获及分组校验等内容。

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

在实际中,通常使用较多是前端的校验,比如页面中js校验,对于安全要求较高的建议在服务端也要进行校验。服务端校验可以是在控制层conroller,也可以是在业务层service,controller校验页面请求的参数的合法性,在服务端控制层conroller的校验,不区分客户端类型(浏览器、手机客户端、远程调用);service层主要校验关键业务参数,仅限于service接口中使用的参数。这里主要总结一下何如使用springmvc中controller的校验。

使用hibernate validator校验框架,导入pom.xml:

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.11.Final</version>
</dependency>

配置校验器

在springmvc.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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 处理器适配器:HandlerAdapter。所有处理器适配器都实现了HandlerAdapter接口-->
    <!-- SimpleControllerHandlerAdapter适配器能执行实现了Controller接口的Handler
    所以,现在配置了这个适配器的话,所有的处理器Handler必须要实现Controller接口才行。
-->
    <!--<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />-->
    <!--<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />-->

    <!--&lt;!&ndash; 配置Handler &ndash;&gt;-->
    <!--&lt;!&ndash;<bean name="/queryItems.action" class="com.cx.controller.ItemsController1" />&ndash;&gt;-->
    <!--<bean id="itemsController1" class="com.cx.controller.ItemsController1" />-->
    <!--<bean id="itemsController2" class="com.cx.controller.ItemsController2" />-->

    <!--&lt;!&ndash; 配置处理器映射器-->
    <!--将bean的name作为url进行查找,需要在配置Handler时指定beanname(就是url)-->
 <!--&ndash;&gt;-->
    <!--&lt;!&ndash;<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />&ndash;&gt;-->

    <!--<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">-->
        <!--<property name="mappings">-->
            <!--<props>-->
                <!--<prop key="/queryItems1.action">itemsController1</prop>-->
                <!--<prop key="/queryItems2.action">itemsController2</prop>-->
            <!--</props>-->
        <!--</property>-->
    <!--</bean>-->

    <!--<bean class="com.cx.controller.ItemsController3" />-->
    <!--<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping "></bean>-->
    <!--<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter "></bean>-->

    <context:component-scan base-package="com.cx.controller"/>

    <mvc:annotation-driven/>
    <mvc:annotation-driven conversion-service="conversionService" validator="validator"></mvc:annotation-driven>
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="converters">
            <list>
                <bean class="com.cx.controller.CustomDateConverter"></bean>
            </list>
        </property>
    </bean>

    <!-- 配置校验器 -->
    <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <!-- 校验器,使用hibernate校验器 -->
        <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
        <!-- 指定校验使用的资源文件,在文件中配置校验错误信息,如果不指定则默认使用classpath下面的ValidationMessages.properties文件 -->
        <property name="validationMessageSource" ref="messageSource"/>
    </bean>
    <!-- 校验错误信息配置文件 -->
    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <!-- 资源文件名 -->
        <property name="basenames">
            <list>
                <value>classpath:CustomValidationMessage</value>
            </list>
        </property>
        <!-- 资源文件编码格式 -->
        <property name="fileEncodings" value="utf-8"/>
        <!-- 对资源文件内容缓存时间,单位秒 -->
        <property name="cacheSeconds" value="120"/>
    </bean>
    <!-- 配置视图解析器
    进行jsp解析,默认使用jstl标签,classpath下得有jstl的包
-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" />
</beans>

配置规则就是bean和property属性,别把class和文件名写错了就行,这里有个配置是资源文件名,这个文件中我们将会配置一些错误信息。配置好了校验器后,需要将校验器注入到处理器适配器中,还是在springmvc.xml文件中,将我们配好的validator注入进去,如下: 

validator

在pojo中添加校验

hibernate校验框架提供了很多注解校验:

注解运行时检查
@AssertFalse被注解的元素必须为false
@AssertTrue被注解的元素必须为true
@DecimalMax(value)被注解的元素必须为一个数字,其值必须小于等于指定的最小值
@DecimalMin(Value)被注解的元素必须为一个数字,其值必须大于等于指定的最小值
@Digits(integer=, fraction=)被注解的元素必须为一个数字,其值必须在可接受的范围内
@Future被注解的元素必须是日期,检查给定的日期是否比现在晚
@Max(value)被注解的元素必须为一个数字,其值必须小于等于指定的最小值
@Min(value)被注解的元素必须为一个数字,其值必须大于等于指定的最小值
@NotNull被注解的元素必须不为null
@Null被注解的元素必须为null
@Past(java.util.Date/Calendar)被注解的元素必须过去的日期,检查标注对象中的值表示的日期比当前早
@Pattern(regex=, flag=)被注解的元素必须符合正则表达式,检查该字符串是否能够在match指定的情况下被regex定义的正则表达式匹配
@Size(min=, max=)被注解的元素必须在制定的范围(数据类型:String, Collection, Map and arrays)
@Valid递归的对关联对象进行校验, 如果关联对象是个集合或者数组, 那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验
@CreditCardNumber对信用卡号进行一个大致的验证
@Email被注释的元素必须是电子邮箱地址
@Length(min=, max=)被注解的对象必须是字符串的大小必须在制定的范围内
@NotBlank被注解的对象必须为字符串,不能为空,检查时会将空格忽略
@NotEmpty被注释的对象必须为空(数据:String,Collection,Map,arrays)
@Range(min=, max=)被注释的元素必须在合适的范围内 (数据:BigDecimal, BigInteger, String, byte, short, int, long and 原始类型的包装类 )
@URL(protocol=, host=, port=, regexp=, flags=)被注解的对象必须是字符串,检查是否是一个有效的URL,如果提供了protocol,host等,则该URL还需满足提供的条件

首先在自己的pojo中需要验证的属性上添加相应的验证注解: 

package com.cx.pojo;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.Date;

public class Items {
    private Integer id;

    @Size(min=1,max=30,message="{items.name.length.error}")
    private String name;

    private Float price;

    private String pic;

    @NotNull(message="{items.createtime.isNull}")
    private Date createtime;

    private String detail;

    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 == null ? null : name.trim();
    }

    public Float getPrice() {
        return price;
    }

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

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic == null ? null : pic.trim();
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }

    public String getDetail() {
        return detail;
    }

    public void setDetail(String detail) {
        this.detail = detail == null ? null : detail.trim();
    }
}

 我们看到注解中可以指定message,那么这个message中的内容是错误消息配置文件中对应的key,取出来的就是对应的错误消息,所以针对这两个错误消息,我们写一下配置文件: 

配置文件

捕获校验错误信息

上面已经将校验相关的配置都配好了,接下来就需要在controller的方法中捕获校验结果中的错误信息,然后将这些错误信息传到前台去显示。那么controller的方法中该如何去捕获呢?如下: 

 捕获错误信息

可以看出,在需要校验的pojo前边添加@Validated,在需要校验的pojo后边添加BindingResult bindingResult来接收校验出错信息。值得注意的是:@Validated和BindingResult bindingResult是配对出现,并且形参顺序是固定的(一前一后)。这样就可以顺利接收到错误信息了。

分组校验

 上面已经能完成springmvc的校验功能了,但是有个问题:刚刚是在pojo中定义了校验规则,但是pojo是被多个controller使用的,现在假如两个不同的controller使用的校验规则是不一样的,简单来说,一个controller不需要去校验生产日期,只要校验一下商品名称即可,另一个controller两个都要校验,这样就没法做了,因为两个controller都使用同一个pojo。 
  为了解决这个问题,我们可以定义多个校验分组(其实是一个java接口),分组中定义有哪些规则,每个controller方法使用不同的校验分组即可。看一下下面的例子就明白了: 

首先定义一个校验分组:

public interface ValidGroup1 {

    //接口中不需要定义任何方法,仅仅是对不同的校验规则进行分组
    //此分组只校验商品名称的长度

}

然后我们在刚刚的pojo中,添加这个分组,如下:

分组校验

再看一下想要校验这个name字段的controller中是如何配置的: 

huoqu 

这样该controller就不会去校验生产日期的字段了,通过这种方式可以解决不同的controller校验不同字段的问题。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值