引言
在日常的接口开发过程中,为了防治参数对业务造成影响,我们经常需要对接口的参数个数进行验证,例如在登录的时候需要校验用户名和密码是否为空,添加用户的时候检验用户邮箱地址、手机号格式是否正确,如果使用 if … esle…. 进行参数校验则会显得代码太过臃肿,代码可读性差不宜维护,在这种情况下,推荐使用注解来实现参数检验。
一、参数校验的特点
二、常用注解
-
@NotNull:值不能为null;
-
@NotEmpty:字符串、集合或数组的值不能为空,即长度大于0;
-
@NotBlank:字符串的值不能为空白,即不能只包含空格;
-
@Size:字符串、集合或数组的大小是否在指定范围内;
-
@Min:数值的最小值;
-
@Max:数值的最大值;
-
@DecimalMin:数值的最小值,可以包含小数;
-
@DecimalMax:数值的最大值,可以包含小数;
-
@Digits:数值是否符合指定的整数和小数位数;
-
@Pattern:字符串是否匹配指定的正则表达式;
-
@Email:字符串是否为有效的电子邮件地址;
-
@AssertTrue:布尔值是否为true;
-
@AssertFalse:布尔值是否为false;
-
@Future:日期是否为将来的日期;
-
@Past:日期是否为过去的日期;
三、代码示例
3.1 创建项目,添加依赖
<!-- 如果spring-boot版本小于2.3.x,spring-boot-starter-web会自动传入hibernate-validator依赖。如果spring-boot版本大于2.3.x,则需要手动引入依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
3.2 创建示例实体类
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDto {
@NotBlank(message = "姓名不能为空")
@Schema(description = "姓名")
private String name;
@NotNull(message = "年龄不能为空")
@Schema(description = "年龄")
@Min(value = 0, message = "年龄不能小于0")
@Max(value = 200, message = "年龄不能大于200")
private Integer age;
//性别只允许为男或女
@NotBlank(message = "性别不能为空")
@Pattern(regexp = "^(男|女)$", message = "性别必须为'男'或'女'")
@Schema(description = "性别")
private String sex;
@Valid
@Schema(description = "嵌套对象")
private TestDtoObj testDtoObj;
}
import com.example.demo.annotation.PhoneNumber;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.URL;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestDtoObj {
@PhoneNumber
@NotBlank(message = "手机号1不能为空")
@Schema(description = "手机号1")
private String phone1;
@Pattern(regexp = "^1[3-9]\d{9}$", message = "无效的手机号码格式")
@NotBlank(message = "手机号不能为空")
@Schema(description = "手机号2")
private String phone2;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 16, message = "密码长度必须在6到16个字符之间")
@Schema(description = "密码")
private String password;
@NotBlank(message = "邮箱不能为空")
@Pattern(regexp = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", message = "邮箱格式不正确")
@Schema(description = "邮箱")
private String email;
@Digits(integer = 4, fraction = 2, message = "整数位数必须在4位以内小数位数必须在2位以内")
@Schema(description = "小数")
private Double num;
@URL(message = "url格式错误")
@Schema(description = "地址")
private String url;
@Past(message = "日期必须为过去日期")
@Schema(description = "过去日期")
private LocalDate pastDate;
@Future(message = "日期必须为将来日期")
@Schema(description = "将来日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private LocalDateTime futureDate;
}
3.3定义特定异常全局拦截方法
Validator框架 抛出的特定异常为MethodArgumentNotValidException,该异常会将我们在参数校验注解自定义的message返回到e.getBindingResult().getFieldError().getDefaultMessage()中
/**
* 全局异常拦截
*
* @author zyw
*/
@Slf4j
@RestControllerAdvice
public class BaseExceptionHandler {
/**
* 拦截参数校验异常
* @param e
* @param request
* @return
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public CommonResult<?> handleGlobalException(MethodArgumentNotValidException e, HttpServletRequest request) {
log.error("请求地址'{}',发生系统异常'{}'", request.getRequestURI(), e.getBindingResult().getFieldError().getDefaultMessage());
return CommonResult.ECEPTION(ResultCode.PARAMETER_EXCEPTION, e.getBindingResult().getFieldError().getDefaultMessage());
}
}
3.4 定义校验类进行测试
import com.example.demo.config.CommonResult;
import com.example.demo.model.dto.TestDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@RestController
@Slf4j
@RequestMapping("knife4j")
@Tag(name = "knife4j测试控制器")
public class Knife4jController {
@PostMapping("/parameterCheck")
@Operation(summary = "参数校验", description = "嵌套参数校验-测试")
public CommonResult<TestDto> parameterCheck(@Validated @RequestBody TestDto dto) {
return CommonResult.SUCCESS(dto);
}
}
3.5 测试
原文始发于微信公众号(Java技术前沿):SpringBoot实战:如何优雅的进行参数校验
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/299638.html