使用spring-boot-starter-validation做参数校验

本文介绍如何使用Spring Boot Starter Validation进行参数校验,包括添加依赖、常用注解及自定义注解的创建过程。

添加依赖

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

常用的几个注解

在这里插入图片描述
在这里插入图片描述

自己做一个注解

参考已有注解

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * The annotated element must not be {@code null}.
 * Accepts any type.
 *
 * @author Emmanuel Bernard
 */
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { })
public @interface NotNull {

	String message() default "{javax.validation.constraints.NotNull.message}";

	Class<?>[] groups() default { };

	Class<? extends Payload>[] payload() default { };

	/**
	 * Defines several {@link NotNull} annotations on the same element.
	 *
	 * @see javax.validation.constraints.NotNull
	 */
	@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
	@Retention(RUNTIME)
	@Documented
	@interface List {

		NotNull[] value();
	}
}

自己写注解

第一步

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {IsMobileValidator.class })
public @interface  IsMobile {
	
	boolean required() default true;
	
	String message() default "手机号码格式错误";

	Class<?>[] groups() default { };

	Class<? extends Payload>[] payload() default { };
}

第二步

public class IsMobileValidator implements ConstraintValidator<IsMobile, String> {

	private boolean required = false;
	
	public void initialize(IsMobile constraintAnnotation) {
		required = constraintAnnotation.required();
	}

	public boolean isValid(String value, ConstraintValidatorContext context) {
		if(required) {
			return ValidatorUtil.isMobile(value);
		}else {
			if(StringUtils.isEmpty(value)) {
				return true;
			}else {
				return ValidatorUtil.isMobile(value);
			}
		}
	}

}

public class ValidatorUtil {
	
	private static final Pattern mobile_pattern = Pattern.compile("1\\d{10}");
	
	public static boolean isMobile(String src) {
		if(StringUtils.isEmpty(src)) {
			return false;
		}
		Matcher m = mobile_pattern.matcher(src);
		return m.matches();
	}

Spring Boot 中,使用 `spring-boot-starter-validation` 实现分组参数校验,主要依赖于 `@Validated` 注解和分组接口的定义。与 `@Valid` 不同,`@Validated` 支持分组校验,可以在不同的业务场景下对参数的不同属性进行有选择的校验。 ### 实现步骤 1. **定义校验分组接口** 创建两个或多个空接口,分别表示不同的校验组。例如,`CreateGroup` 和 `UpdateGroup`。 ```java public interface CreateGroup {} public interface UpdateGroup {} ``` 2. **在实体类中使用分组** 在实体类的字段上使用 Bean Validation 注解(如 `@NotBlank`, `@Min` 等),并通过 `groups` 属性指定该字段属于哪个校验组。 ```java import javax.validation.constraints.Min; import javax.validation.constraints.NotBlank; public class User { @NotBlank(message = "用户名不能为空", groups = CreateGroup.class) private String username; @Min(value = 18, message = "年龄必须大于等于18岁", groups = {CreateGroup.class, UpdateGroup.class}) private int age; @NotBlank(message = "邮箱不能为空", groups = UpdateGroup.class) private String email; // Getter and Setter } ``` 3. **在 Controller 中启用分组校验** 使用 `@Validated` 注解标注 Controller 类,并在方法参数使用 `@Valid` 同时指定分组。注意 `@Validated` 是类级别的注解,而 `@Valid` 用于方法参数。 ```java import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; @RestController @Validated public class UserController { @PostMapping("/createUser") public String createUser(@Validated(CreateGroup.class) @RequestBody User user) { return "用户创建成功"; } @PostMapping("/updateUser") public String updateUser(@Validated(UpdateGroup.class) @RequestBody User user) { return "用户更新成功"; } } ``` 4. **异常处理(可选)** 可以通过 `@ControllerAdvice` 或 `@ExceptionHandler` 捕获 `MethodArgumentNotValidException`,统一返回校验失败的信息。 ```java import org.springframework.http.HttpStatus; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import java.util.HashMap; import java.util.Map; @RestControllerAdvice public class ValidationHandler { @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public Map<String, String> handleValidationExceptions(MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors().forEach((error) -> { String fieldName = ((org.springframework.validation.FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return errors; } } ``` ### 总结 通过上述步骤,可以在 Spring Boot 应用中实现基于 `@Validated` 的分组参数校验机制,从而在不同的业务场景下对参数进行精细化控制,确保数据的完整性与一致性[^2]。 ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值