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

Java SpringBoot 通过javax.validation.constraints下的注解,实现入参数据自动验证
如果碰到 @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);
  
    @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;
    }
}

运行结果如下
image

原文链接:https://www.cnblogs.com/vipsoft/p/17314686.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:如何实现 Java SpringBoot 自动验证入参数据的有效性 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • Java代码实现对properties文件有序的读写的示例

    Java代码实现对properties文件有序的读写的示例 在Java中读写properties文件是非常常见的操作,但是在默认情况下properties文件是无序的,这就会给我们的读写操作带来一定的困扰。本攻略将详细介绍Java代码如何实现对properties文件有序的读写操作。 1. 针对JDK7及以下版本的实现方式 在Java 7及以下版本中,虽然无…

    Java 2023年6月15日
    00
  • Tomcat配置https SSL证书的项目实践

    Tomcat配置https SSL证书的项目实践 在Web应用程序中添加SSL证书是提高安全性的一种重要方法。Tomcat是一个流行的Java Web服务器,它可以通过配置https SSL证书来提供安全的访问。 什么是SSL证书? SSL(Secure Socket Layer)证书是一种用于保护Web通信的数字证书。它通过加密网站和用户之间的数据传输来确…

    Java 2023年6月2日
    00
  • Mybatis 动态SQL搭建环境的全过程

    Mybatis 动态SQL是 Mybatis 框架中非常重要的一个功能,可以通过此功能来动态生成 SQL 语句,从而满足不同场景需求。下面是 Mybatis 动态SQL搭建环境的全过程的详细介绍: 1. 环境准备 需要准备以下环境: JDK Maven MySQL数据库 Mybatis IDE插件(建议使用IDEA) 2. 创建项目 使用 Maven 创建一…

    Java 2023年6月1日
    00
  • jdk中动态代理异常处理分析:UndeclaredThrowableException

    当使用 JDK 动态代理时,如果目标方法抛出一个未在代理接口上声明的异常时,会发生 UndeclaredThrowableException 异常。这个异常用于包装仅在运行时可知的受检查异常或 “错误”(Error)类型的异常(例如 java.io.IOException 或 java.lang.OutOfMemoryError),从而响应于在虚拟机集线器(…

    Java 2023年5月27日
    00
  • Springboot全局异常捕获及try catch区别解析

    Springboot全局异常捕获及try catch区别解析 在Spring Boot中,异常是常见的问题。出于代码健壮性和良好的用户体验考虑,我们需要对异常进行处理。本文将介绍如何使用全局异常处理来处理Spring Boot中的异常,并且对”try catch”语句进行解析比较。 全局异常处理 全局异常处理是指在系统发生异常时,通过一个统一的异常处理类进行…

    Java 2023年5月27日
    00
  • Mybatis通过数据库表自动生成实体类和xml映射文件

    “Mybatis通过数据库表自动生成实体类和xml映射文件”的完整攻略主要包括以下步骤:使用Mybatis Generator插件生成实体类和xml映射文件,配置Mybatis Generator插件,使用命令行或maven命令运行生成器。 使用Mybatis Generator插件生成实体类和xml映射文件 Mybatis Generator是一个能够根据…

    Java 2023年5月20日
    00
  • Java如何获取Date的“昨天”与“明天”示例代码

    获取Date的“昨天”与“明天”可以通过以下步骤实现: 步骤一:获取当前日期 首先,我们需要获取当前的日期。Java中可以使用java.util.Date类来表示日期时间。可以通过new Date()方法获取到当前的日期: Date today = new Date(); 步骤二:计算“昨天” 要计算“昨天”,我们需要通过java.util.Calendar…

    Java 2023年5月20日
    00
  • 老生常谈java中的Future模式

    关于Future模式在Java中的应用,以下是详细讲解的攻略: 什么是Future模式 Future模式是一种常用的设计模式,它将一个耗时的操作在后台执行,然后把执行结果返回给调用方。在执行操作的同时,调用方可以继续执行自己的逻辑,等到操作完成时再获取结果,这样可以避免阻塞调用方。 在Java中,Future模式通常使用Java Future接口来实现。该接…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部