如何对请求参数进行参数校验

在基于Spring Boot的Java项目中,对前端传来的QO(Query Object)对象进行参数校验是保障数据有效性和安全性的核心步骤。以下是具体的实现方法、常用校验类型及示例:


一、校验实现步骤

1. 添加依赖

确保项目中引入Spring Boot Validation依赖(基于Hibernate Validator实现):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
2. 在QO类中声明校验注解

在QO对象的字段上使用JSR 303规范提供的校验注解。 (一开始知道简单的就可以了,没必要记住,不会的现查就ok,用多了就熟了)
示例:定义一个接收用户查询条件的QO类:

public class UserQueryQo {
    @NotBlank(message = "用户名不能为空")
    @Size(min = 2, max = 20, message = "用户名长度需在2-20之间")
    private String username;

    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式错误")
    private String phone;

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

    @NotNull(message = "用户类型不能为空")
    @Range(min = 1, max = 3, message = "用户类型需为1-3")
    private Integer userType;

    @Valid  // 嵌套对象校验
    private AddressQo address;
}
3. 在Controller中触发校验

在接口方法的QO参数前添加@Valid@Validated注解,以触发自动校验:

@RestController
public class UserController {
    @PostMapping("/query")
    public Result queryUsers(@RequestBody @Validated UserQueryQo qo) {
        // 业务逻辑
        return Result.ok();
    }
}

二、常用校验类型及注解

校验类型注解作用示例
非空校验@NotBlank校验字符串非空且长度>0(仅适用于String)@NotBlank(message = "用户名不能为空")
数值范围校验@Min / @Max限制数值的最小/最大值@Min(value = 18, message = "年龄需≥18")
正则表达式校验@Pattern校验字符串是否符合正则表达式`@Pattern(regexp = "^[男
集合/数组校验@NotEmpty校验集合/数组非空@NotEmpty(message = "角色列表不能为空")
日期校验@Future / @Past校验日期是否为未来/过去时间@Future(message = "生效时间必须为未来时间")
嵌套对象校验@Valid递归校验嵌套对象的字段@Valid private AddressQo address;

三、高级校验场景

1. 分组校验

为不同接口场景定义不同的校验规则:

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

// QO类中使用分组
public class UserQo {
    @NotNull(groups = {UpdateGroup.class}, message = "用户ID不能为空")
    private Long id;

    @NotBlank(groups = {CreateGroup.class, UpdateGroup.class}, message = "用户名不能为空")
    private String username;
}

// Controller中指定分组
@PostMapping("/create")
public Result createUser(@RequestBody @Validated(CreateGroup.class) UserQo qo) { ... }
2. 自定义校验

通过自定义注解实现复杂逻辑(如跨字段校验):

// 定义注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateRangeValidator.class)
public @interface ValidDateRange {
    String message() default "结束时间必须晚于开始时间";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

// 实现校验逻辑
public class DateRangeValidator implements ConstraintValidator<ValidDateRange, UserQueryQo> {
    @Override
    public boolean isValid(UserQueryQo qo, ConstraintValidatorContext context) {
        return qo.getEndTime().after(qo.getStartTime());
    }
}

// 在QO类上应用注解
@ValidDateRange
public class UserQueryQo { ... }

四、统一异常处理

校验失败时,Spring Boot会抛出MethodArgumentNotValidException,需全局捕获并返回友好提示:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result handleValidationException(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        String errorMsg = result.getFieldErrors().stream()
                .map(error -> error.getField() + ": " + error.getDefaultMessage())
                .collect(Collectors.joining(", "));
        return Result.fail(400, errorMsg);
    }
}

五、完整示例

QO类

public class OrderQueryQo {
    @NotBlank(message = "订单号不能为空")
    private String orderId;

    @NotNull(message = "用户ID不能为空")
    @Min(value = 1, message = "用户ID需为正整数")
    private Long userId;

    @Pattern(regexp = "^(pending|shipped|delivered)$", message = "状态值不合法")
    private String status;

    @Valid
    private PaymentInfoQo paymentInfo;
}

Controller接口

@PostMapping("/orders")
public Result queryOrders(@RequestBody @Validated OrderQueryQo qo) {
    // 业务逻辑
    return Result.ok();
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值