数据校验(Validation)实现全局异常处理 + 国际化 + @Valid 三位一体方案

Validation参数校验 这里是修真院后端小课堂,每篇分享文从 八个方面深度解析后端知识/技能,本篇分享的是: 【Validation参数校验】 【修真院Java小课堂】Validation参数校验 大家好,我是IT修真院北京分院第35期一枚正直纯洁善良的Java程序员,今天给大家分享一下,修真院官网Java(职业)任务二,深度思考中的知识点——Validation参数校验 背景介绍 数据的校验是交互式网站一个不可或缺... 阅读详情

✅ Spring Boot 项目构建完整的输入校验体系

—— 全局异常处理 + 国际化 + @Valid 三位一体方案


在企业级 Spring Boot 项目中,统一、健壮、可维护的输入校验机制 是保障系统稳定性和用户体验的关键。本文将详细说明如何结合:

  • ✅ @Valid 参数校验
  • ✅ 国际化消息(多语言支持)
  • ✅ 全局异常处理器(@ControllerAdvice)

构建一个 高内聚、低耦合、易扩展 的输入校验体系。


📌 一、目标

实现以下功能:

  1. 所有接口参数自动校验(JSON、表单、路径变量等)
  2. 校验失败返回结构化错误信息
  3. 错误提示支持中文、英文等多语言
  4. 统一异常处理,避免重复代码
  5. 支持嵌套对象校验(级联)
  6. 可扩展自定义业务异常

📁 二、项目结构示例

src/main/java/
├── controller/
│   └── UserController.java
├── dto/
│   ├── UserRegisterDTO.java
│   └── AddressDTO.java
├── exception/
│   ├── GlobalExceptionHandler.java
│   └── ErrorResponse.java
src/main/resources/
├── application.yaml
├── messages.properties          # 默认中文
├── messages_zh.properties      # 中文
├── messages_en.properties       # 英文


📦 三、Maven 依赖(pom.xml)

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- 参数校验支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
</dependencies>

✅ Spring Boot 3.x 使用 jakarta.validation,2.x 使用 javax.validation


🛠️ 四、配置文件:application.yaml

server:
  port: 8080

spring:
  # 配置国际化资源文件
  messages:
    basename: messages        # 资源文件前缀(自动加载 messages.properties)
    encoding: UTF-8           # 文件编码
    cache-duration: 10s       # 缓存时间
    fallback-to-system-locale: true  # 找不到语言时回退系统语言

  # 开启参数绑定异常处理(可选)
  web:
    resources:
      add-mappings: true

🌍 五、国际化资源文件

1. messages.properties(默认中文)

# messages.properties
notblank.username=用户名不能为空
size.username=用户名长度必须在 {min} 到 {max} 个字符之间
email.email=邮箱格式不正确
pattern.phone=手机号格式不正确
min.age=年龄不能小于 {value}
max.age=年龄不能大于 {value}
positive.balance=账户余额必须为正数
decimal.max.discount=折扣率不能大于 {value}
decimal.min.discount=折扣率不能小于 {value}
past.birthday=生日必须是过去的时间
future.membership=会员到期时间必须是将来的时间
notempty.hobbies=兴趣爱好不能为空
size.hobbies=兴趣爱好数量必须在 {min} 到 {max} 之间
size.tags=标签数量不能超过 {max} 个
notblank.province=省不能为空
notblank.city=市不能为空
size.detail=详细地址不能超过 {max} 个字符

2. messages_en.properties(英文)

# messages_en.properties
notblank.username=Username is required
size.username=Username must be between {min} and {max} characters
email.email=Email format is invalid
pattern.phone=Phone number format is invalid
min.age=Age cannot be less than {value}
max.age=Age cannot be greater than {value}
positive.balance=Balance must be positive
decimal.max.discount=Discount cannot be greater than {value}
decimal.min.discount=Discount cannot be less than {value}
past.birthday=Birthday must be in the past
future.membership=Membership expiry must be in the future
notempty.hobbies=Hobbies cannot be empty
size.hobbies=Number of hobbies must be between {min} and {max}
size.tags=Tags cannot exceed {max} items
notblank.province=Province is required
notblank.city=City is required
size.detail=Detail address cannot exceed {max} characters

✅ 注意:{value}, {min}, {max} 是占位符,会自动替换为实际值


📦 六、数据传输对象(DTO)

1. 嵌套地址对象:AddressDTO.java

package com.example.demo.dto;

import jakarta.validation.constraints.*;

/**
 * 地址信息 DTO
 * 用于用户注册中的地址信息
 */
@Getter
@Setter
public class AddressDTO {

    @NotBlank(message = "{notblank.province}")
    private String province;

    @NotBlank(message = "{notblank.city}")
    private String city;

    @NotBlank(message = "{notblank.detail}")
    @Size(max = 200, message = "{size.detail}")
    private String detail;

    // Getters and Setters
}

2. 用户注册对象:UserRegisterDTO.java

package com.example.demo.dto;

import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

/**
 * 用户注册请求 DTO
 * 包含所有注册字段,并使用 Validation 注解进行校验
 */
@Getter
@Setter
public class UserRegisterDTO {

    @NotBlank(message = "{notblank.username}")
    @Size(min = 3, max = 20, message = "{size.username}")
    private String username;

    @Email(message = "{email.email}")
    private String email;

    @NotBlank(message = "{notblank.phone}")
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "{pattern.phone}")
    private String phone;

    @Min(value = 18, message = "{min.age}")
    @Max(value = 120, message = "{max.age}")
    private Integer age;

    @Positive(message = "{positive.balance}")
    private BigDecimal balance;

    @DecimalMin(value = "0.0", inclusive = true, message = "{decimal.min.discount}")
    @DecimalMax(value = "1.0", inclusive = true, message = "{decimal.max.discount}")
    private Double discount;

    @NotEmpty(message = "{notempty.hobbies}")
    @Size(min = 1, max = 5, message = "{size.hobbies}")
    private List<String> hobbies;

    @Size(max = 3, message = "{size.tags}")
    private String[] tags;

    @Past(message = "{past.birthday}")
    private LocalDate birthday;

    @Future(message = "{future.membership}")
    private LocalDate membershipExpiryDate;

    // 使用 @Valid 实现级联校验
    @Valid
    private AddressDTO address;

    // Getters and Setters(略)
}

⚠️ 七、全局异常处理器:GlobalExceptionHandler.java

package com.example.demo.exception;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import java.util.*;

/**
 * 全局异常处理器
 * 统一处理参数校验异常、类型转换异常等,返回标准化错误响应
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    @Autowired
    private MessageSource messageSource; // 用于加载国际化消息

    /**
     * 处理 @Valid 校验失败异常(@RequestBody 场景)
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationException(
            MethodArgumentNotValidException ex) {

        Locale locale = LocaleContextHolder.getLocale(); // 获取当前语言环境
        List<String> errors = new ArrayList<>();

        // 遍历所有字段错误,获取国际化消息
        for (FieldError fieldError : ex.getBindingResult().getFieldErrors()) {
            String msg = messageSource.getMessage(fieldError, locale);
            errors.add(fieldError.getField() + ": " + msg);
        }

        ErrorResponse response = new ErrorResponse(
                HttpStatus.BAD_REQUEST.value(),
                "参数校验失败",
                errors,
                new Date()
        );

        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
    }

    /**
     * 处理方法参数校验异常(如 @RequestParam 上使用 @NotBlank)
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseEntity<ErrorResponse> handleConstraintViolation(
            ConstraintViolationException ex) {

        Locale locale = LocaleContextHolder.getLocale();
        List<String> errors = new ArrayList<>();

        for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
            String msg = messageSource.getMessage(
                    violation.getMessageTemplate(),
                    violation.getMessageParameters(),
                    locale
            );
            errors.add(violation.getPropertyPath() + ": " + msg);
        }

        ErrorResponse response = new ErrorResponse(
                HttpStatus.BAD_REQUEST.value(),
                "参数约束违反",
                errors,
                new Date()
        );
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
    }

    /**
     * 兜底异常:捕获所有未处理的异常
     * 防止服务器错误暴露敏感信息
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleGeneralException(Exception ex) {
        // 生产环境应记录日志
        // logger.error("服务器内部错误", ex);

        ErrorResponse response = new ErrorResponse(
                HttpStatus.INTERNAL_SERVER_ERROR.value(),
                "服务器内部错误,请稍后重试",
                Collections.singletonList("请联系管理员"),
                new Date()
        );
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
    }
}

📦 八、统一错误响应体:ErrorResponse.java

package com.example.demo.exception;

import java.util.Date;
import java.util.List;

/**
 * 统一错误响应格式
 * 所有异常返回都使用此结构
 */
@Getter
@Setter
public class ErrorResponse {
    private int status;        // HTTP 状态码
    private String message;    // 错误摘要
    private List<String> details; // 具体错误信息
    private Date timestamp;    // 发生时间

    public ErrorResponse(int status, String message, List<String> details, Date timestamp) {
        this.status = status;
        this.message = message;
        this.details = details;
        this.timestamp = timestamp;
    }

    // Getters and Setters
}

🖥️ 九、Controller 示例:UserController.java

package com.example.demo.controller;

import com.example.demo.dto.UserRegisterDTO;
import org.springframework.web.bind.annotation.*;

/**
 * 用户控制器
 * 演示如何使用 @Valid 进行参数校验
 */
@RestController
@RequestMapping("/api/users")
public class UserController {

    /**
     * 用户注册接口
     * 使用 @Valid 自动触发校验,失败时由 GlobalExceptionHandler 捕获
     */
    @PostMapping("/register")
    public ResponseEntity<String> register(@Valid @RequestBody UserRegisterDTO dto) {
        // 如果走到这里,说明校验通过
        return ResponseEntity.ok("用户 [" + dto.getUsername() + "] 注册成功!");
    }
}

✅ 不需要手动处理 BindingResult,由全局异常处理器统一处理


🧪 十、测试示例

1. 中文请求(默认)

POST http://localhost:8080/api/users/register
Content-Type: application/json
Accept-Language: zh-CN

{
  "username": "ab",
  "email": "invalid",
  "phone": "12345678901",
  "age": 15,
  "balance": -100,
  "discount": 1.5,
  "hobbies": [],
  "tags": ["a","b","c","d"],
  "birthday": "2025-01-01",
  "membershipExpiryDate": "2024-01-01",
  "address": {
    "province": "",
    "city": "北京",
    "detail": ""
  }
}

响应(中文):

{
  "status": 400,
  "message": "参数校验失败",
  "details": [
    "username: 用户名长度必须在 3 到 20 个字符之间",
    "email: 邮箱格式不正确",
    "phone: 手机号格式不正确",
    "age: 年龄不能小于 18",
    "balance: 账户余额必须为正数",
    "discount: 折扣率不能大于 1.0",
    "hobbies: 兴趣爱好不能为空",
    "tags: 标签数量不能超过 3 个",
    "birthday: 生日必须是过去的时间",
    "membershipExpiryDate: 会员到期时间必须是将来的时间",
    "address.province: 省不能为空",
    "address.detail: 详细地址不能为空"
  ],
  "timestamp": "2025-04-05T10:30:00"
}

2. 英文请求

POST http://localhost:8080/api/users/register
Content-Type: application/json
Accept-Language: en-US

{ ... 同上数据 ... }

响应(英文):

{
  "status": 400,
  "message": "参数校验失败",
  "details": [
    "username: Username must be between 3 and 20 characters",
    "email: Email format is invalid",
    ...
  ],
  "timestamp": "2025-04-05T10:30:00"
}

✅ 十一、体系优势总结

特性说明
✅ 统一格式所有错误返回结构一致,前端易处理
✅ 多语言支持通过 Accept-Language 自动切换
✅ 零重复代码无需每个接口写 if (errors.hasErrors())
✅ 支持级联校验嵌套对象也能自动校验
✅ 易于扩展可添加业务异常、权限异常等
✅ 生产就绪错误信息不暴露堆栈,安全可靠

📝 十二、生产建议

  1. 日志记录:在 GlobalExceptionHandler 中添加 logger.error() 记录原始异常。
  2. 自定义业务异常:
    public class BusinessException extends RuntimeException {
        private int code;
        // ...
    }
    
  3. 分组校验:使用 @Validated + 分组实现“新增”和“更新”不同规则。
  4. 性能监控:对高频接口的校验性能进行压测。
  5. 文档生成:配合 Swagger,使用 @Schema 注解生成 API 文档。

🎯 总结

通过 @Valid + 国际化 + 全局异常处理 三位一体方案,你可以构建一个:

标准化、国际化、可维护、高可用 的输入校验体系

这套方案已在多个企业级项目中验证,具备高度参考价值,推荐作为 Spring Boot 项目的标准实践。

SpringBoot 2.7+ 参数校验国际化:整合Validation与MessageSource的5个关键步骤 本文详细介绍了在SpringBoot 2.7+环境中实现参数校验国际化的完整解决方案,包括基础配置、校验注解集成、全局异常处理与响应封装等5个关键步骤。通过整合Validation与MessageSource,开发者可以轻松构建支持多语言的Web应用,提升用户体验。 阅读详情

相关推荐

@Valid 注解详解 Java Bean Validation的前世今生

Spring @Valid 注解 校验实体属性 1 @Valid 介绍 1.1 前言 1.2 Bean Validation 1.3 关于validation包 1.3 关于Spring Hibernate Validator支持的约束集信息(constraints) 2 简单的使用 2.1配置项 2.1.1 maven – jar包引入 2.1.2 SpringMVC配置 2.2 实现方式 2.2.1 @Valid + BindingResult + ja

m0_54852350的博客 288

Spring Boot Validator以及国际化(i18n)

本文实验的软件环境如下: Spring Boot 2.1.8.RELEASE JDK 1.8 IDEA2019.2.3 Gradle 5.6.2 最近在研究Spring Boot 的Validator以及国际化

choimroc的博客 2万+

Spring中@Validated与@Valid校验注解使用详解及实战示例

理想的DTO设计应当具备清晰的职责划分和完整的自我验证能力。以下是一个典型的用户资料更新对象:@Past(message = "出生日期必须早于当前日期")此处引入了占位符${...}风格的消息模板,便于后续国际化支持。例如,在中可定义:user.id.required=用户ID是必填项user.name.notblank=姓名不能为空user.name.size=姓名长度必须在{min}到{max}个字符之间Spring会在校验失败时自动插值替换{min}{max}

weixin_30653091的博客 1385

Spring Boot Validation提示信息国际化配置

本文结合Spring Boot 2.5和2.6版本分别介绍下Spring Boot Validation如何集成自定义国际化验证提示信息。

罗小爬的技术宝书 4677

ATAC-seq差异分析实战:从原始数据到GO富集(R/Bioconductor全流程)

本文提供了ATAC-seq差异分析的完整R/Bioconductor实战流程,涵盖从原始数据准备、一致峰集构建、计数矩阵生成,到使用DESeq2进行差异可及性分析,以及差异峰的基因组注释与GO富集分析。文章详细讲解了关键步骤、参数设置和常见问题,旨在帮助研究者获得可靠且可解释的生物学结果。

weixin_29246195的博客 228

Wi-Fi Sigma测试系统

Wi-Fi Sigma测试系统是Wi-Fi联盟(WFA)提出的一套全自动的WiFi认证测试系统,几乎涵盖的所有Wi-Fi的功能及性能(throughput)的自动化测试。该系统正逐步取代以前的WiFi认证测试系统。

Ke8323的博客 1万+

SpringBoot 使用validation数据校验之国际化问题怎么搞?满满的方案,值得收藏 - 第411篇

SpringBoot 使用validation数据校验之国际化问题怎么搞?满满的方案,值得收藏 - 第411篇

qq_44600824的博客 3620

学Simulink——基于Simulink的AUTOSAR架构下电机控制软件组件建模

本文详细介绍了在Simulink中基于AUTOSAR架构开发电机控制软件组件(SWC)的全流程。主要内容包括:首先阐述了AUTOSAR架构对汽车电子系统开发的价值,包括提高软件复用率、降低集成成本和改善验证环境。然后重点讲解了在Simulink中构建电机控制SWC的具体步骤:从创建AUTOSAR组件模型、定义数据端口和服务端口,到搭建FOC控制算法、配置运行实体,最后生成AUTOSAR描述文件和验证RTE接口。文章还提供了与基础软件(BSW)的集成方案、工程实践要点和常见问题解决方案,并以大众MEB平台等实

amy_mhd的博客 67

Validator校验框架使用i18n国际化

validator校验框架实现国际化提示、.i18n国际化带有参数的信息以及国际化参数

u012785397的博客 1832

AutoSAR实验视频讲解:相关资料下载

AutoSAR实验视频讲解:闪烁一颗LED实验【相关资料下载】 总目录 为了方便大家自己的实验顺利进行,这里我们准备了一些实验中可能用到的资料供大家使用 介绍 这里主要是三个文件: MyApp_Core.0是我们的用户代码,在工程集成那集将会讲解 McalConfig.arxml就是我们的Mcal导出文件,用于导入到DaVinci中生成代码 CAN.dbc文件是我们的通信矩阵文件 以上几个文件都是简单的配置,不具有实际项目的实用性,大家仅供参考 // 顺便吐槽一句:百度网盘的吃相真的难看 下载连接

雪云飞星的博客 6668

SAP Gateway 中事务码 /IWFND/MAINT_SERVICE 的用法介绍

本文系统梳理了SAP Gateway中/IWFND/MAINT_SERVICE事务码的核心功能与运维实践。作为OData服务管理中樞,它支持服务注册激活、ICF节点配置、系统别名绑定、批量处理等关键操作。文章详解了服务目录、ICF节点、系统别名的配置要点,提供了批量激活、缓存清理、性能监控等实用技巧,并针对常见陷阱(如传输配置、删除残留)给出解决方案。通过制造业批量激活、零售业OAuth集成等案例,展示了事务码在企业级应用中的实际价值,为SAP Gateway运维提供了一套完整的治理清单。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 302

Spring国际化和Validation

validation与国际化结合,自定义注解校验,内部方法上使用注解校验

weixin_46488959的博客 2216

铁路场景雷达点云目标识别与追踪系统

本文介绍了一种基于毫米波雷达的铁路货运车站安全监控系统。该系统采用分布式架构,通过多个毫米波雷达节点采集点云数据,经过坐标转换、多雷达融合等处理后,利用机器学习算法实现列车、行人等目标的实时识别与追踪。系统包含数据采集层、处理层、目标识别层、追踪层、预警决策层和可视化层,能够克服传统视频监控受环境影响大的缺点,实现全天候可靠监测。文中详细展示了雷达数据解析和点云预处理的代码实现,包括坐标转换、数据格式解析和体素网格滤波等关键技术。该系统可有效预警铁路场景下的碰撞风险,提升货运车站的安全管理水平。

huanghm88的专栏 124

【SpringBoot框架篇】26.集成spring-boot-starter-validation对接口参数校验

文章目录1.常规验证2.使用validation验证2.1.添加依赖2.2.常用注解2.3.在pojo类中添加需要使用的注解2.4.在接口入参处添加@Valid2.5.添加全局异常处理类返回校验错位提示信息 1.常规验证 以下面的登录接口为例,需要手动去验证参数是否存在,这种写法繁琐且不太优雅。 @RestController public class LoginController { @RequestMapping("/login") public String test(@Reque

皓亮君的博客 2583

信号处理仿真:自适应信号处理_(8).自适应信道均衡

在无线通信系统中,信道的多径效应和时变特性会导致信号的失真,从而影响通信质量。自适应信道均衡技术通过实时调整均衡器的参数,以补偿信道失真,提高信号的质量和可靠性。本节将详细介绍自适应信道均衡的原理、算法和实现方法,并通过具体的仿真例子来说明其应用。

2401_87715305的博客 1039

论文阅读:NeurIPS 2024 JailbreakBench: An Open Robustness Benchmark for Jailbreaking Large Language Model

论文指出评估越狱攻击存在挑战,如缺乏评估标准、成本和成功率计算方法不一致、许多研究无法复现。为解决这些问题,作者提出了JailbreakBench,这是一个开源基准测试,包含以下组件:持续更新的越狱提示库(jailbreak artifacts)。包含100种行为的越狱数据集,符合OpenAI的使用政策。标准化的评估框架,包括威胁模型、系统提示、聊天模板和评分函数。跟踪各种LLMs攻击和防御性能的排行榜。

CSPhD-winston的博客 1431

validation校验标准

校验注解即可以添加到实体字段上验证整个对象,也可以添加在请求的方法参数上,验证单个参数。在请求参数列表 添加 BindingResult result。除上述配置外,为了实现返回前端错误信息,还需要以下操作。在方法接受的对象参数前添加注解@Valid。如果要在service层做校验,同理。

优快云博客技术,java高级工程师,业务层架构师,高级管理认证,毕业设计可以联系我 1149

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Spring Boot 参数校验 Validation 入门

文章摘要:本文介绍了在Spring Boot中使用Hibernate Validator进行参数校验的方法。概述了参数校验的重要性,列举了Bean Validation和Hibernate Validator提供的常用校验注解,并对比了@Valid和@Validated注解的区别。文章包含快速入门指南,展示如何通过引入依赖、配置Application类来实现对Controller和Service层的参数校验。核心要点包括:1)参数校验是保证API可靠性的必要环节;2)通过注解方式实现声明式校验;3)@Val

无忧无虑的Coding~~~ 1216

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Spring Boot全局异常捕获处理及参数校验详解

在没有统一异常处理的情况下,每个Controller方法都需要编写try-catch代码块来处理可能抛出的异常,这会导致代码冗余、难以维护。全局异常处理可以将异常处理逻辑集中管理,提供统一的响应格式,并简化Controller层的代码。创建一个类,加上注解。可以指定或等属性来限定作用范围。java// ...自定义业务异常类,然后在全局异常处理器中专门处理它。java// getterBean Validation是Java EE规范,用于对Java对象进行约束校验。

油墨香^-^的博客 977

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

SpringBoot Validation:从注解到全局异常处理的优雅校验实践

本文详细介绍了SpringBoot Validation在参数校验中的优雅实践,从基础注解使用到全局异常处理,涵盖分组校验、嵌套对象校验和自定义校验器等高级技巧。通过对比传统if-else方式,展示了声明式校验的高效性,并提供了性能优化和常见问题排查方案,帮助开发者构建健壮的Web应用。

weixin_29758911的博客 259

Java Jakarta Validation 实战指南:从参数校验到分组、自定义注解和全局异常处理

Jakarta Validation是Java生态中的数据校验标准规范,通过注解方式在模型类上定义校验规则(如@NotBlank、@Email等),结合Hibernate Validator实现校验逻辑,并由Spring Boot集成到Web请求流程中。开发时只需在Controller方法参数添加@Valid注解即可自动触发校验,无需手动编写if判断。常用校验注解包括非空检查(@NotNull)、字符串格式(@Pattern)、数值范围(@Min/Max)、日期(@Past)等,能有效减少重复校验代码。Sp

tangPHP的博客 258

Spring Boot接口参数校验:注解、分组与全局异常处理

接口参数校验是后端开发中最基础也最容易失控的环节。手工if-else散落各处,往往导致业务逻辑被大量重复校验代码淹没。Bean Validation与Hibernate Validator通过声明式注解,将校验规则直接绑定在数据模型上,配合全局异常处理统一输出错误结构,从根本上提升了Spring Boot应用的参数处理效率。本文从注解校验的基本用法切入,深入分组校验、自定义校验器、嵌套对象与集合校验等通用技术,结合工程实践剖析常见坑点与性能边界。适合从手写判断转型的开发者,以及希望重构复杂校验逻辑的项目团队

weixin_31309419的博客 242

Spring Validation校验框架原理

本文深入解析Spring Validation校验框架的核心原理,从接口体系到实际执行机制。主要内容包括: 核心接口体系:Validator执行校验流程,ConstraintValidator实现校验逻辑,ConstraintViolation封装错误信息 约束注解解析:每个校验注解必须包含message、groups等属性,通过@Constraint指定关联的ConstraintValidator 执行机制:框架通过遍历约束、调用isValid方法、收集校验结果完成验证过程 功能特性:支持级联校验、分组校

qq_26394753的博客 251

使用 @Valid 实现 REST 接口请求参数校验

💡 注意:如果你使用的是 spring-boot-starter-web,则 validation 是默认引入的,无需额外添加。@Size(min = 6, max = 20, message = "密码长度应在 6 到 20 个字符之间")"password": "密码长度应在 6 到 20 个字符之间",@Email(message = "邮箱格式不正确")"username": "用户名不能为空","age": "年龄必须大于等于 18 岁""email": "邮箱格式不正确",

hrl9185dkwe的博客 368
上一篇: 数据校验(Validation) 常用的数据校验注解及其作用
下一篇: 1、Cart-Service 服务设计规范文档
龙茶清欢
博客等级 码龄7年 3720粉丝 375原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值