《Spring Boot参数校验终极指南:从零到一构建滴水不漏的API防护体系》


🌟 前言

“为什么前端传的参数总是不合法?”
“如何避免写一堆if判断来校验参数?”
本文将手把手教你使用Spring Boot的校验框架,从基础注解→嵌套校验→自定义规则→全局异常处理,彻底告别参数校验的烦恼!


一、参数校验为什么重要?

1.1 血的教训

  • 案例1:用户手机号传了null → 短信接口报空指针
  • 案例2:订单金额传入负数 → 财务对账出问题
  • 案例3:邮箱格式错误 → 营销邮件发送失败

1.2 校验的核心目标

  • 安全性:防止SQL注入、XSS攻击
  • 健壮性:避免脏数据污染数据库
  • 友好性:给前端明确的错误提示

二、Spring Boot参数校验的四种姿势

2.1 原始方式(不推荐)

public String createUser(String name, Integer age) {  
    if (name == null || name.isEmpty()) {  
        throw new IllegalArgumentException("姓名不能为空");  
    }  
    if (age == null || age < 1 || age > 150) {  
        throw new IllegalArgumentException("年龄不合法");  
    }  
    // 业务逻辑...  
}  

缺点:代码臃肿、重复劳动


2.2 注解校验(推荐✨)

步骤1:添加依赖

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-validation</artifactId>  
</dependency>  

步骤2:在DTO类上加注解

@Data  
public class UserDTO {  
    @NotBlank(message = "姓名不能为空")  
    private String name;  

    @NotNull(message = "年龄必填")  
    @Min(value = 1, message = "年龄不能小于1岁")  
    @Max(value = 150, message = "年龄不能超过150岁")  
    private Integer age;  

    @Email(message = "邮箱格式错误")  
    private String email;  
}  

步骤3:在Controller中添加@Valid

@PostMapping("/users")  
public Result<?> createUser(@RequestBody @Valid UserDTO userDTO) {  
    // 业务逻辑...  
}  

三、常用校验注解大全

注解作用示例
@NotNull值不能为null校验对象类型字段
@NotBlank字符串不能为空用户名、地址等
@Min/@Max数值范围限制年龄、金额
@Pattern正则表达式校验手机号、身份证号
@Email邮箱格式校验用户注册邮箱
@Size集合或字符串长度限制密码长度、列表大小
@Future/@Past日期校验生日、活动时间

四、嵌套校验与分组校验

4.1 嵌套对象校验

@Data  
public class OrderDTO {  
    @Valid  // 必须加此注解  
    private UserDTO user;  

    @NotEmpty  
    private List<@Valid ProductDTO> products;  
}  

@Data  
public class ProductDTO {  
    @NotBlank  
    private String name;  
}  

4.2 分组校验(按场景区分规则)

// 定义分组接口  
public interface CreateGroup {}  
public interface UpdateGroup {}  

// DTO中使用分组  
@Data  
public class UserDTO {  
    @Null(groups = CreateGroup.class)  
    @NotNull(groups = UpdateGroup.class)  
    private Long id;  
}  

// Controller指定分组  
@PostMapping("/users")  
public Result<?> createUser(@Validated(CreateGroup.class) @RequestBody UserDTO dto) {  
    //...  
}  

五、自定义校验规则

5.1 实现手机号校验器

步骤1:定义注解

@Target({ElementType.FIELD})  
@Retention(RetentionPolicy.RUNTIME)  
@Constraint(validatedBy = PhoneValidator.class)  
public @interface Phone {  
    String message() default "手机号格式错误";  
    Class<?>[] groups() default {};  
    Class<? extends Payload>[] payload() default {};  
}  

步骤2:编写校验逻辑

public class PhoneValidator implements ConstraintValidator<Phone, String> {  
    private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");  

    @Override  
    public boolean isValid(String value, ConstraintValidatorContext context) {  
        if (value == null) return true; // 允许为空,配合@NotBlank使用  
        return PHONE_PATTERN.matcher(value).matches();  
    }  
}  

步骤3:在DTO中使用

@Phone  
private String mobile;  

六、全局异常处理(统一返回格式)

@RestControllerAdvice  
public class GlobalExceptionHandler {  

    // 捕获参数校验异常  
    @ExceptionHandler(MethodArgumentNotValidException.class)  
    public Result<?> handleValidException(MethodArgumentNotValidException e) {  
        List<String> errors = e.getBindingResult().getFieldErrors().stream()  
                .map(item -> item.getField() + ": " + item.getDefaultMessage())  
                .collect(Collectors.toList());  
        return Result.error(400, "参数错误", errors);  
    }  
}  

响应示例

{  
  "code": 400,  
  "message": "参数错误",  
  "data": [  
    "mobile: 手机号格式错误",  
    "age: 年龄不能小于1岁"  
  ]  
}  

七、常见坑点与解决方案

7.1 校验不生效?

  • 检查1:Controller方法是否添加@Valid@Validated
  • 检查2:DTO字段是否使用正确的注解(如String用@NotBlank而非@NotNull
  • 检查3:是否遗漏spring-boot-starter-validation依赖

7.2 国际化消息

resources下创建ValidationMessages.properties

user.name.notblank=用户名不能为空  
user.age.min=年龄不能小于{value}岁  

在注解中引用:

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

📚 实战总结

Spring Boot参数校验体系  
├─ 基础校验:内置注解+@Valid  
├─ 高级技巧  
│  ├─ 嵌套校验  
│  ├─ 分组校验  
│  └─ 自定义校验  
└─ 异常处理  
   ├─ 全局异常捕获  
   └─ 统一响应格式  

#SpringBoot教程 #参数校验 #API开发 #小白必备 #优快云博文

你在参数校验中踩过哪些坑?
评论区分享你的经历,点赞最高的送《Spring Boot实战派》电子书!🚀


相关推荐

(转载需授权,侵权必究)

好的,关于这个问题我们今天就先分享到这里,希望能帮助到屏幕前为代码发愁的您。如果觉得有帮助,希望能在Taobao搜索“鹿溪IT工作室”买一个Android小项目来练手,友友们给个好评,支持一下创作者不易!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值