springboot验证框架

Spring Boot支持JSR-303、Bean验证框架。在Spring MVC中,只需要使用@Valid注解标注在方法参数上,Spring Boot即可对参数对象进行校验,校验结果放在BindingResult对象中。

建议导包

<!-- hibernate验证框架 -->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.17.Final</version>
            <scope>compile</scope>
        </dependency>

1、JSR-303

注解验证:

空检查

  @Null,验证对象是否为空;

  @NotNull,验证对象不为空;

  @NotBlank,验证字符串不为空或者不是空字符串;

  @NotEmpty,验证对象不为null,或者集合不为空;

长度检查

  @Size(min=,max=),验证对象长度,可支持字符串、集合;

  @Length,字符串大小;

数值检测

  @Min,验证数字是否大于等于指定的值;

  @Max,验证数字是否小于等于指定的值;

  @Digits,验证数字是否符合指定格式,如@Digits(integer=9,fraction=2);

  @Range,验证数据是否在指定的范围内,如@Range(min=1,max=1000);

其他

  @Email,验证是否为邮件格式,为null则不做校验;

  @Pattern,验证String对象是否负责正则表达式的规则;

例:

复制代码
package com.gcz.entity.bean;

import lombok.Data;

import javax.validation.constraints.*;

/**
* @author guocz
* @date 20210616
* 工作清单
*/
@Data
public class WorkInfoForm {

/**
* id
*/
@NotNull(message = "id不能为空")
private Long id;

/**
* 名字
*/
@Size(min = 3, max = 20, message = "名字长度不规范")
private String name;

/**
* 邮件
*/
@Email
private String email;

}
复制代码

  通常,不同的业务逻辑会有不同的验证逻辑,比如对于WorkInfoForm来说,当更新的时候,id必须不为null,但增加的时候,id必须为null。

  JSR-303定义了group概念,每个校验注解都必须支持。校验注解作用在字段上的时候,可以指定一个或者多个group,当Spring Boot校验对象的时候,也可以指定校验的上下文属于哪个group。这样,只有group匹配的时候,校验注解才能生效。

例:

1、设置组别AddWorkInfo

复制代码
package com.gcz.service;

import javax.validation.groups.Default;

/**
 * @author guocz
 * @date 20210616
 * 新增工作清单
 */
public interface AddWorkInfo extends Default {
}
复制代码

2、设置组别UpdateWorkInfo

复制代码
package com.gcz.service;

import javax.validation.groups.Default;

/**
 * @author guocz
 * @date 20210616
 * 更新工作清单
 */
public interface UpdateWorkInfo extends Default {
}
复制代码

3、所要校验的Bean进行分组校验设置

复制代码
package com.gcz.entity.bean;

import com.gcz.service.AddWorkInfo;
import com.gcz.service.UpdateWorkInfo;
import lombok.Data;

import javax.validation.constraints.*;


/**
 * @author guocz
 * @date 20210616
 * 工作清单
 */
@Data
public class WorkInfoForm {

    /**
     * id
     */
    @NotNull(groups = AddWorkInfo.class, message = "id不能为空")
    @Null(groups = UpdateWorkInfo.class, message = "id必须为空")
    private String id;

    /**
     * 名字
     */
    @Size(min = 3, max = 20, message = "名字长度不规范")
    @NotBlank(message = "名字不能为空")
    private String name;

    /**
     * 邮件
     */
    @Email
    private String email;

}
复制代码

4、在使用时选好分组

复制代码
package com.gcz.controller;

import com.gcz.entity.bean.WorkInfoForm;
import com.gcz.service.AddWorkInfo;
import com.gcz.service.UpdateWorkInfo;
import org.springframework.stereotype.Controller;

import org.springframework.validation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author guocz
 * @date 20210616
 * 工作清单
 */
@Controller
@RequestMapping("/workInfo")
public class WorkInfoController {

    @ResponseBody
    @RequestMapping("/addworkinfo.html")
    public void addWorkInfo(@Validated({UpdateWorkInfo.class}) WorkInfoForm workInfoForm, BindingResult result){
        if (result.hasErrors()) {
            List<ObjectError> list = result.getAllErrors();
            FieldError error = (FieldError) list.get(0);
            System.out.println(error.getObjectName() + "," + error.getField() + "," + error.getDefaultMessage());
        }
    }
}
复制代码

参数workInfoForm使用了@Validated注解,将触发Spring的校验,并将验证结果存放到BindingResult对象中,如果Controller没有提供BindingResult对象,则Spring MVC将抛出异常,需要采用通用异常处理

2、MVC中使用@Validated

在Controller中,只需要给方法参数加上@Validated即可触发一次校验。

3、自定义校验

 自定义注解校验:

参考:(自定义注解详细介绍)https://blog.csdn.net/xsp_happyboy/article/details/80987484

例:

1、自定义注解

复制代码
package com.gcz.entity.verify.customverify;

import com.gcz.entity.verify.customverify.constraint.WorkOverTimeValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * @author guocz
 * @date 20210618
 * 工作时间超时验证注解
 */

// @Constraint注解声明用什么类来实现验证,
@Constraint(validatedBy = {WorkOverTimeValidator.class})
@Documented
@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface WorkOverTime {
    String message() default "工作时间过长,不能超过{max}小时";
    float max() default 5;
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
复制代码

2、注解实现类

复制代码
package com.gcz.entity.verify.customverify.constraint;

import com.gcz.entity.verify.customverify.WorkOverTime;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @author guocz
 * @date 20210618
 * 工作时间超时验证类
 */
public class WorkOverTimeValidator implements ConstraintValidator<WorkOverTime, Float> {

    WorkOverTime work;

    float max;

    @Override
    public void initialize(WorkOverTime work) {
        // 获取注解的定义
        this.work = work;
        max = work.max();
    }

    @Override
    public boolean isValid(Float aFloat, ConstraintValidatorContext constraintValidatorContext) {
        if (aFloat == null) {
            return true;
        }
        return aFloat <= max;
    }


}
复制代码

3、使用注解

复制代码
package com.gcz.entity.req;

import com.gcz.entity.verify.customverify.WorkOverTime;
import lombok.Data;

/**
 * @author guocz
 * @date 20210618
 * 工作时间
 */
@Data
public class WorkTimeReq {

    @WorkOverTime(max = 2)
    private float workTime;
}
复制代码

4、调用

复制代码
package com.gcz.controller;

import com.gcz.entity.req.WorkTimeReq;
import org.springframework.stereotype.Controller;
import org.springframework.validation.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

/**
 * @author guocz
 * @date 20210619
 * 工作时间
 */
@Controller
@RequestMapping("/worktime")
public class WorkTimeController {

    @ResponseBody
    @RequestMapping("/workOverTime.html")
    public void workOverTime(@Validated WorkTimeReq req, BindingResult result){
        if (result.hasErrors()) {
            List<ObjectError> list = result.getAllErrors();
            FieldError error = (FieldError) list.get(0);
            System.out.println(error.getObjectName() + "," + error.getField() + "," + error.getDefaultMessage());
        }
    }
}
复制代码
posted @   幻影黑子  阅读(817)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示