Loading...
墨滴

远方聂努达

2021/12/01  阅读:49  主题:极简黑

Java 中优雅的参数校验方法

Java 中优雅的参数校验方法学习

简单了解

Spring 官方在 SpringBoot 文档中,关于参数校验(Validation)给出的解决方案是这样的:

The method validation feature supported by Bean Validation 1.1 is automatically enabled as long as a JSR-303 implementation (e.g. Hibernate validator) is on the classpath. This allows bean methods to be annotated with javax.validation constraints on their parameters and/or on their return value. Target classes with such annotated methods need to be annotated with the @Validated annotation at the type level for their methods to be searched for inline constraint annotations.

For instance, the following service triggers the validation of the first argument, making sure its size is between 8 and 10

@Service
@Validated
public class MyBean {

    public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
            Author author) {
        ...
    }

}

SpringBoot 文档

翻译以下就是使用 JSR-303 规范,直接利用注解进行参数校验。

PS:(JSR-303 是 JAVA EE 6 中的一项子规范,叫做 Bean Validation,官方参考实现是 Hibernate Validator)

实际体验

  1. Java Bean对象中引入注解,这里我们先不对各个注解代表的含义展开解释。
@Data
@EqualsAndHashCode(callSuper = true)
public class Org extends BaseEntity implements Serializable {

 private static final long serialVersionUID = 6414776805478207026L;
  
 @NotNull((message = "部门id不能为空" )
 private Long id;
  
 @NotBlank(groups = { Update.class })
 @Size(max = 64, min = 1, groups = { Insert.class, Update.class })
 private String orgName;
}
  1. 在Controller 层对应的方法上添加如下注解: @Validated
public Result addOrg(@Validated(Insert.class) @RequestBody SysOrg sysOrg) {
..... do something
}
  1. 为什么要做参数验证?
  • 防止恶意用户通过精心构造的参数破坏我们的系统
  • 保证我们的业务有序进行
  • 即便前端已经校验过,因为我们不能保证我们收到的请求都是由我们的前端程序发出

详细了解

JSR303 规范默认提供了以下几种约束注解的定义。

Constraint
含义
@AssertFalse 被注解的元素必须是否定值,支持:boolean/Boolean/null
@AssertTrue 被注解的元素必须是肯定值,支持范围与 @AssertFalse相同
@DecimalMax 被注解的元素必须是一个数字,其值必须小于或等于指定的最大值。支持: BigDecimal/BigIntege/CharSequence/byte/short/int/ long及其包装类/null;由于精度范围限制,不支持double,float及其包装类
@DecimalMin 被注解的元素必须是一个数字,其值必须大于或等于指定的最小值。支持范围与 @DecimalMax 相同
@Digits 被注解的元素必须是可接受范围内的数字。支持范围与 @DecimalMax 相同
@Email 被注解的元素必须是字符串,必须是格式正确的电子邮件地址。支持: CharSequence/null
@Future 被注解的元素必须是未来的某个时刻、日期或时间。支持:java.util.Date/java.util.Calendar/java.time.Instant/java.time.LocalDate/java.time.LocalDateTime/java.time.LocalTime/java.time.MonthDay/java.time.OffsetDateTime/java.time.OffsetTime/java.time.Year/java.time.YearMonth/java.time.ZonedDateTime/java.time.chrono.HijrahDate/java.time.chrono.JapaneseDate/java.time.chrono.MinguoDate/java.time.chrono.ThaiBuddhistDate/null
@FutureOrPresent 被注解的元素必须是现在或者未来的某个时刻、日期或时间。支持范围与 @Future 相同
@Max 被注解的元素必须是一个数字,值必须小于或等于指定的最大值。支持: BigDecimal/BigInteger/byte/short/int/long及其包装类/null;由于精度范围限制,不支持double,float及其包装类
@Min 被注解的元素必须是一个数字,其值必须大于或等于指定的最小值。支持范围与 @Max 相同
@Negative 被注解的元素必须是严格的负数(0 被视为无效值)。支持范围与 @Max 相同
@NegativeOrZero 被注解的元素必须为负数或者0。支持范围与 @Max 相同
@NotBlank 被注解的元素不能为空,并且必须至少包含一个非空白字符。支持: CharSequence
@NotEmpty 被注解的元素不得为 null 或为空。支持: CharSequence(评估字符序列的长度)/Collection(评估集合容量)/Map(评估Map容量)/Array(评估数组长度)
@NotNull 被注解的元素不得为 null;支持任意类型
@Null 被注解的元素必须为 null;支持任意类型
@Past 被注解的元素必须是过去的某个时刻、日期或时间。支持范围同Future
@PastOrPresent 被注解的元素必须是过去或现在的某个时刻、日期或时间。支持范围与 @Future 相同
@Pattern 被注解的元素必须匹配指定的正则表达式。正则表达式遵循 Java 正则表达式约定,参见 java.util.regex.Pattern。支持: CharSequence/null
@Positive 被注解的元素必须是严格的正数(即 0 被视为无效值)。支持范围与 @Max 相同
@PositiveOrZero 被注解的元素必须是正数或 0。支持范围与 @Max 相同
@Size 被注解的元素必须在指定的边界(包括)之间。支持: CharSequence(评估字符序列的长度)/Collection(评估集合容量)/Map(评估Map容量)/Array(评估数组长度)/null

未完待续

上文我们已经基本了解如何使用以及各自代表的含义了,但是应该有人已经发现文中对应的校验注解上面添加了 groups 属性,并且在对应的 Controller 层 中使用 @Validated 指定使用了某个分组。下文我们将会学习如何添加参数校验分组以及如何自定义校验注解。

- END -

远方聂努达

2021/12/01  阅读:49  主题:极简黑

作者介绍

远方聂努达