如何实现 Java SpringBoot 自动验证入参数据的有效性

科技资讯 投稿 6000 0 评论

如何实现 Java SpringBoot 自动验证入参数据的有效性

如果碰到 @NotEmpty 否则不生效,注意看下 @RequestBody 前面是否加上了@Valid

Validation常用注解汇总

Constraint 详细信息
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@NotBlank 被注释的元素不能为空(空格视为空)
@NotEmpty 被注释的元素不能为空 (允许有空格
@Size(max, min 被注释的元素的大小必须在指定的范围内
@Min(value 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Pattern(value 被注释的元素必须符合指定的正则表达式
@DecimalMin(value 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Digits (integer, fraction 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期

示例

 /**
   * 用户名
   */
  @NotBlank(message = "用户名不能为空"
  private String username;
  /**
   * 用户真实姓名
   */
  @NotBlank(message = "用户真实姓名不能为空"
  private String name;

  /**
   * 密码
   */
  @Pattern(regexp = "^(?:(?=.*[A-Z](?=.*[a-z](?=.*[0-9](?=.*[^A-Za-z0-9](?=^[^\\u4e00-\\u9fa5]{0,}$.{8,20}$", message = "密码过于简单有被盗风险,请保证密码大于8位,并且由大小写字母、数字,特殊符号组成"  
  private String password;

  /**
   * 邮箱
   */
  @NotBlank(message = "邮箱不能为空"
  @Email(message = "邮箱格式不正确"
  private String email;

  /**
   * 手机号
   */
  @NotBlank(message = "手机号不能为空"
  @Pattern(regexp = "^(1[0-9]\\d{9}$", message = "手机号格式不正确"
  private String mobile;

Demo

入参对象上,添加注解及说明

package com.vipsoft.web.entity;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.Serializable;

/**
 * 定时任务调度
 */
public class QuartzJob implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 任务序号
     */
    private long jobId;

    /**
     * 任务名称
     */
    @NotBlank(message = "任务名称不能为空"
    @Size(max = 10, message = "任务名称不能超过10个字符"
    private String jobName;

    /**
     * 任务组名
     */
    @NotBlank(message = "任务组名不能为空"
    @Size(max = 10, message = "任务组名不能超过10个字符"
    private String jobGroup;

    /**
     * 调用目标字符串
     */
    private String invokeTarget;

    /**
     * 执行表达式
     */
    private String cronExpression;

    /**
     * cron计划策略 0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行
     */
    private String misfirePolicy = "0";

    /**
     * 并发执行 0=允许,1=禁止
     */
    private String concurrent;

    /**
     * 任务状态(0正常 1暂停)
     */
    private String status;

    /**
     * 备注
     */
    private String remark;
}

Controller @RequestBody 前面必须加上 @Valid 否则不生效

import javax.validation.Valid;

@RestController
@RequestMapping("schedule"
public class ScheduleController {

    private Logger logger = LoggerFactory.getLogger(ScheduleController.class;

    @Autowired
    IQuartzJobService jobService;

    @RequestMapping("/add"
    public ApiResult addTask(@Valid @RequestBody QuartzJob param throws Exception {
        logger.info("添加调度任务 => {} ", JSONUtil.toJsonStr(param;
        
        return new ApiResult("添加成功";
    }
}

异常处理,统一返回对象,方便前端解析
GlobalExceptionHandler

package com.vipsoft.web.exception;

import cn.hutool.core.util.StrUtil;
import com.vipsoft.web.utils.ApiResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.List;

/**
 * 全局异常处理器
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class;
 
    /**
     * 处理自定义异常
     */
    @ExceptionHandler(CustomException.class
    public ApiResult handleException(CustomException e {
        // 打印异常信息
        logger.error("### 异常信息:{} ###", e.getMessage(;
        return new ApiResult(e.getCode(, e.getMessage(;
    }

    /**
     * 参数错误异常
     */
    @ExceptionHandler({MethodArgumentNotValidException.class, BindException.class}
    public ApiResult handleException(Exception e {
        if (e instanceof MethodArgumentNotValidException {
            MethodArgumentNotValidException validException = (MethodArgumentNotValidException e;
            BindingResult result = validException.getBindingResult(;
            StringBuffer errorMsg = new StringBuffer(;
            if (result.hasErrors( {
                List<ObjectError> errors = result.getAllErrors(;
                errors.forEach(p -> {
                    FieldError fieldError = (FieldError p;
                    errorMsg.append(fieldError.getDefaultMessage(.append(",";
                    logger.error("### 请求参数错误:{" + fieldError.getObjectName( + "},field{" + fieldError.getField( + "},errorMessage{" + fieldError.getDefaultMessage( + "}";
                };
                return new ApiResult(6001, errorMsg.toString(;
            }
        } else if (e instanceof BindException {
            BindException bindException = (BindException e;
            if (bindException.hasErrors( {
                logger.error("### 请求参数错误: {}", bindException.getAllErrors(;
            }
        }
        return new ApiResult(6001, "参数无效";
    }

    /**
     * 处理HttpRequestMethodNotSupporte异常
     * @param e
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class
    public Object methodHandler(HttpRequestMethodNotSupportedException e {
        // 打印异常信息
        logger.error("### 异常信息:{} ###", e.getMessage(;
        return new ApiResult(6000, e.getMessage(;
    }

    /**
     * 处理所有不可知的异常
     */
    @ExceptionHandler(Exception.class
    public ApiResult handleOtherException(Exception e {
        // 打印异常信息
        logger.error("### 系统内部错误:{} ###", e.getMessage(, e;
        String warnMsg = StrUtil.isEmpty(e.getMessage( ? "### 系统内部错误 ###" : e.getMessage(;
        return new ApiResult(6000, "系统内部错误", e.getMessage(;
    }

}

统一返回对像 ApiResult

package com.vipsoft.web.utils;


//import com.github.pagehelper.PageInfo;

import java.io.Serializable;

public class ApiResult implements Serializable {

    /**
     * 返回编码 0:失败、1:成功
     */
    private int code;

    /**
     * 返回消息
     */
    private String message;

    /**
     * 返回对象
     */
    private Object data;

    /**
     * 分页对象
     */
    private Page page;

    public ApiResult( {
        this.code = 1;
        this.message = "请求成功";
    }

    public ApiResult(Integer code, String message {
        this.code = code;
        this.message = message;
    }

    public ApiResult(Integer code, String message, Object data {
        this.code = code;
        this.message = message;
        this.setData(data;
    }

    public ApiResult(Object data {
        this.code = 1;
        this.message = "请求成功";
        this.setData(data;
    }

//    public ApiResult(PageInfo pageInfo {
//        this.code = 1;
//        this.message = "请求成功";
//        this.setData(pageInfo.getList(;
//        this.setPage(convertToPage(pageInfo;
//    }
//
//    public Page convertToPage(PageInfo pageInfo {
//        Page result = new Page(;
//        result.setTotalCount(pageInfo.getTotal(;
//        result.setPageNum(pageInfo.getPageNum(;
//        result.setPageCount(pageInfo.getPages(;
//        result.setPageSize(pageInfo.getPageSize(;
//        result.setPrePage(pageInfo.getPrePage(;
//        result.setNextPage(pageInfo.getNextPage(;
//        return result;
//    }

    public int getCode( {
        return code;
    }

    public void setCode(int code {
        this.code = code;
    }

    public String getMessage( {
        return message;
    }

    public void setMessage(String message {
        this.message = message;
    }

    public Object getData( {
        return data;
    }

    public void setData(Object data {
        this.data = data;
    }

    public Page getPage( {
        return page;
    }

    public void setPage(Page page {
        this.page = page;
    }
}

运行结果如下

编程笔记 » 如何实现 Java SpringBoot 自动验证入参数据的有效性

赞同 (30) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽