TIP
在项目中,jakarta.validation
(原 javax.validation
)是 Java Bean Validation API
的实现,用于对 Java Bean
进行验证,可以轻松实现对请求参数、表单数据等的验证。
添加依赖
在 pom.xml
配置文件中添加以下依赖:
js
<!-- 依赖声明 -->
<dependencies>
<!-- spring web 起始依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- validation验证依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
</dependencies>
配置文件
在 xiaomayi-common/xiaomayi-core
核心模块中添加验证器配置类 ValidatorConfiguration
,注册 Bean
对象。
js
package com.xiaomayi.core.config;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
/**
* <p>
* 参数验证类
* </p>
*
* @author 鲲鹏
* @since 2022-07-18
*/
@Configuration
public class ValidatorConfiguration {
/**
* 注册验证Bean对象
*
* @return 返回结果
*/
@Bean
public Validator validator() {
ValidatorFactory validatorFactory =
Validation.byProvider(HibernateValidator.class)
.configure()
// 快速失败返回模式
// .addProperty("hibernate.validator.fail_fast", "true")
// 快速失败模式
.failFast(true)
.buildValidatorFactory();
return validatorFactory.getValidator();
}
/**
* 开启快速返回
* 如果参数校验有异常,直接抛异常,不会进入到 controller,使用全局异常拦截进行拦截
*/
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
// 设置validator模式为快速失败返回
postProcessor.setValidator(validator());
return postProcessor;
}
}
温馨提示
验证器需要添加上述配置,否则实际使用时验证器不生效。
使用案例
jakarta.validation
是 Jakarta EE
的标准 API
,提供了一套统一的验证机制。通过使用标准注解(如 @NotNull、@Size、@Email
等),可以确保验证逻辑的一致性和可移植性。
js
package com.xiaomayi.system.dto.level;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
/**
* <p>
* 职级
* </p>
*
* @author 小蚂蚁云团队
* @since 2024-03-23
*/
@Data
@Schema(name = "职级添加DTO", description = "职级添加DTO")
public class LevelAddDTO {
@Schema(description = "职级名称")
@NotBlank(message = "职级名称不能为空")
@Size(max = 100, message = "职级名称最多100个字符")
private String name;
@Schema(description = "职级状态:1-正常 2-停用")
@NotNull(message = "职级状态不能为空")
@Range(min = 1, max = 2, message = "职级状态值在1-2之间")
private Integer status;
@Schema(description = "职级排序")
@NotNull(message = "职级排序不能为空")
@Min(value = 0, message = "排序不得小于0")
private Integer sort;
}
简化代码
通过注解方式声明验证规则,避免了在业务逻辑中手动编写大量的 if-else
验证代码,减少了代码重复,提升了代码的可读性和可维护性。
js
package com.xiaomayi.admin.controller;
import cn.hutool.http.HttpStatus;
import com.xiaomayi.core.config.AppConfig;
import com.xiaomayi.core.exception.BizException;
import com.xiaomayi.core.utils.R;
import com.xiaomayi.excel.utils.ExcelUtil;
import com.xiaomayi.logger.annotation.RequestLog;
import com.xiaomayi.logger.enums.RequestType;
import com.xiaomayi.system.dto.level.LevelAddDTO;
import com.xiaomayi.system.dto.level.LevelListDTO;
import com.xiaomayi.system.dto.level.LevelPageDTO;
import com.xiaomayi.system.dto.level.LevelUpdateDTO;
import com.xiaomayi.system.service.LevelService;
import com.xiaomayi.system.vo.level.LevelExcelVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* <p>
* 职级 前端控制器
* </p>
*
* @author 小蚂蚁云团队
* @since 2024-03-23
*/
@RestController
@RequestMapping("/level")
@Tag(name = "职级管理", description = "职级管理")
@AllArgsConstructor
public class LevelController {
private final LevelService levelService;
/**
* 添加职级
*
* @param levelAddDTO 参数
* @return 返回结果
*/
@Operation(summary = "添加职级", description = "添加职级")
@RequestLog(title = "添加职级", type = RequestType.INSERT)
@PreAuthorize("@pms.hasAuthority('sys:level:add')")
@PostMapping("/add")
public R add(@RequestBody @Validated LevelAddDTO levelAddDTO) {
return levelService.add(levelAddDTO);
}
}
温馨提示
上述代码方法中 @Validated
即用于对 LevelAddDTO
参数的验证。
内置注解
jakarta.validation
提供了丰富的内置注解,覆盖了常见的验证场景。
js
@NotNull:字段不能为空。
@Size:字段长度限制。
@Email:验证邮箱格式。
@Min、@Max:数值范围验证。
@Pattern:正则表达式验证。
使用案例:
java
package com.xiaomayi.system.dto.user;
import com.xiaomayi.xss.annotation.Xss;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
/**
* <p>
* 用户
* </p>
*
* @author 小蚂蚁云团队
* @since 2024-03-23
*/
@Data
@Schema(name = "用户添加DTO", description = "用户添加DTO")
public class UserAddDTO {
@Schema(description = "用户名称")
@NotBlank(message = "用户名称不能为空")
@Size(max = 150, message = "用户名称最多150个字符")
private String realname;
@Schema(description = "用户性别:1-男 2-女 3-保密")
@NotNull(message = "用户性别不能为空")
@Range(min = 1, max = 3, message = "用户性别值在1-3之间")
private Integer gender;
@Schema(description = "用户头像")
@NotBlank(message = "用户头像不能为空")
@Size(max = 255, message = "用户头像最多255个字符")
private String avatar;
@Schema(description = "手机号码")
@NotBlank(message = "手机号码不能为空")
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String mobile;
@Schema(description = "邮箱地址")
@NotBlank(message = "邮箱地址不能为空")
@Email(message = "邮箱格式不正确")
private String email;
@Schema(description = "部门ID")
@NotNull(message = "部门ID不能为空")
@Min(value = 1, message = "部门ID必须大于0")
private Integer deptId;
@Schema(description = "职级ID")
@NotNull(message = "职级ID不能为空")
@Min(value = 1, message = "职级ID必须大于0")
private Integer levelId;
@Schema(description = "岗位ID")
@NotNull(message = "岗位ID不能为空")
@Min(value = 1, message = "岗位ID必须大于0")
private Integer positionId;
@Schema(description = "行政区划")
@NotEmpty(message = "行政区划不能为空")
private String[] city;
@Schema(description = "详细地址")
@NotBlank(message = "详细地址不能为空")
@Size(max = 255, message = "详细地址最多255个字符")
private String address;
@Xss(message = "登录账号不能包含脚本字符")
@Schema(description = "登录账号")
@NotBlank(message = "登录账号不能为空")
@Size(max = 50, message = "登录账号最多50个字符")
private String username;
@Xss(message = "登录密码不能包含脚本字符")
@Schema(description = "登录密码")
@NotBlank(message = "登录密码不能为空")
private String password;
@Schema(description = "加密盐")
private String salt;
@Schema(description = "个人简介")
@Size(max = 500, message = "个人简介最多500个字符")
private String intro;
@Schema(description = "用户状态:1-正常 2-禁用")
@NotNull(message = "用户状态不能为空")
@Range(min = 1, max = 2, message = "用户状态值在1-2之间")
private Integer status;
@Schema(description = "用户备注")
@Size(max = 500, message = "用户备注最多500个字符")
private String note;
@Schema(description = "用户排序")
@NotNull(message = "用户排序不能为空")
@Min(value = 0, message = "排序不得小于0")
private Integer sort;
@Schema(description = "用户角色ID集合")
@NotEmpty(message = "用户角色ID集合不能为空")
private Integer[] roles;
@Schema(description = "租户ID,传值使用")
private Integer tenantId;
}
总结
在项目中使用 jakarta.validation
基于 JDK17
的好处包括:
标准化验证:统一验证机制,提升代码一致性。
减少重复代码:通过注解简化验证逻辑。
无缝集成:与项目深度集成,开箱即用。
丰富的内置注解:覆盖常见验证场景。
自定义验证:支持自定义注解,满足特定需求。
全局异常处理:统一处理验证错误。
提高可测试性:验证逻辑清晰,便于测试。
分组验证:支持多场景验证规则。
国际化支持:适配多语言环境。
提高安全性:防止恶意数据注入。