Spring Boot ——使用javax.validation进行参数校验

本文介绍Java中使用Hibernate Validator进行Bean验证的方法,包括不同注解的使用场景及自定义异常处理,帮助开发者确保数据的有效性和一致性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基本用法

 

实体类

public class UserBean {

     /**
     *    1.@NotNull:不能为null,但可以为empty(""," ","   ")      
     *    2.@NotEmpty:不能为null,而且长度必须大于0 (" ","  ")
     *    3.@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0("test")    即:必须有实际字符
     * 复制代码
     */
    @NotBlank(message="用户名不能为空")
    private String userName;

    @NotBlank(message="年龄不能为空")
    @Pattern(regexp="^[0-9]{1,2}$",message="年龄不正确")
    private String age;

    @AssertFalse(message = "必须为false")
    private Boolean isFalse;
    /**
     * 如果是空,则不校验,如果不为空,则校验
     */
    @Pattern(regexp="^\\d{4}(-)(1[0-2]|0?\\d)\\1([0-2]\\d|\\d|30|31)$",message="出生日期格式不正确")
    private String birthday;

    @Pattern(regexp = "^[M|F|U|m|f|u]{1}$")
    private String gender;

    @Pattern(regexp = "^(MS)?(MR)?(PRO)?(MRS)?(DOC)?$")
    private String civility;

    @Size(min = 1, message = "field names can't be empty")
    private List<String> names = new ArrayList();

}

测试;

@RestController
@RequestMapping("/vh")
public class ValidatorController {
 
    @RequestMapping("/resign")
    public String resign(@RequestBody @Valid  UserBean user ) {
    	
    	
        return "success";
    }
}

如果校验通不过返回这样的报文:

这种方式返回的报文不能控制,我们来看第二种方案:

方式二

工具类;



/**
 * hibernate-validator校验工具类
 */
public class ValidatorUtils {
	private static Validator validator;

	static {
		validator = Validation.buildDefaultValidatorFactory().getValidator();
	}

	/**
	 * 校验对象
	 * 
	 * @param object
	 *            待校验对象
	 * @param groups
	 *            待校验的组
	 * @throws CustomException
	 *             校验不通过,则报RRException异常
	 */
	public static void validateEntity(Object object, Class<?>... groups) throws CustomException {
		Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
		if (!constraintViolations.isEmpty()) {
			ConstraintViolation<Object> constraint = (ConstraintViolation<Object>) constraintViolations.iterator()
					.next();
			throw new CustomException(new ParamResultCode(constraint.getMessage()));
		}
	}

	public static boolean isNotNull(Object obj) {
		try {
			if (obj == null || obj.toString().equals("null") || obj.toString().equals("")) {
				return false;
			}
			return true;
		} catch (Exception e) {
			return true;
		}
	}
}

分组;

/**
 * 新增数据 Group
 */
public interface SaveGroup {
}

 这个分组的意思时当添加数据时这个校验生效

测试:

@RestController
@RequestMapping("/vh")
public class ValidatorController {
 
    @RequestMapping("/resign")
    public String resign(@RequestBody @Valid  UserBean user ) {
    	ValidatorUtils.validateEntity(user , SaveGroup.class);
    	
        return "success";
    }
}

返回结果:

{
    "msg": "用户名不能为空",
    "code": 500
}

推荐使用第二种方式

附录:

@Validated与@Valid 的区别

@Validated:提供了一个分组功能,可以在入参验证时,根据不同的分组采用不同的验证机制,这个网上也有资料,不详述。

@Valid:作为标准JSR-303规范,还没有吸收分组的功能。

注解说明:

Bean验证约束
注解支持的数据类型作用
@AssertFalseBoolean, boolean值等于false
@AssertTrueBoolean, boolean值等于true
@Futurejava.util.Date 等检查给定的日期比当前日期晚.
@Pastjava.util.Date 等检查给定的日期比当前日期早.
@MaxBigDecimal, BigInteger, byte, short, int, long 以及包装类检查该值是否小于或等于约束条件中指定的最大值.
@MinBigDecimal, BigInteger, byte, short, int, long 以及包装类检查该值是否大于或等于约束条件中指定的最小值.
@NotNull任意类型带注释的值不为null.
@Null任意类型带注释的值为null.
@Pattern(regex=, flag=)String检查该字符串是否能够在match指定的情况下被regex定义的正则表达式匹配.
@Size(min=, max=)String,Collection,Map,array检查带注释的元素的大小是否在最小值和最大值之间.
@Valid任何引用数据类型
@CreditCardNumbeString检查信用卡号
@EmailString检查指定的字符串是否为有效的电子邮件地址。
@Length(min=, max=)String确认带注释的字符串在min和max之间.
@NotBlankString值不为null 切不为"", 不为"  "
@NotEmptyString,Collection,Map,array值不为null 或者没有值
@Range(min=, max=)BigDecimal,String, BigInteger, byte, short, int, long 以及包装类值是否位于(包含)指定的最小值和最大值之间。
@SafeHtml(whitelistType=, additionalTags=)检查带注释的值是否包含潜在的恶意片段,如脚本/。为了使用这个约束,jsoup库必须是类路径的一部分。可以选择whitelistType属性预定义白名单类型。您还可以使用additionalTags属性为白名单指定额外的html标记。
@URL(protocol=, host=, port=, regexp=, flags=)String根据RFC2396,检查带注释的字符串是否是有效的URL。如果指定了任何可选参数协议、主机或端口,相应的URL片段必须匹配指定的值。可选参数regexp和旗帜允许指定URL必须匹配的额外正则表达式(包括正则表达式标志)。

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]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

刘彦青-Yannis

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

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

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

打赏作者

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

抵扣说明:

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

余额充值