拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 在方法参数上使用@NotNull

在方法参数上使用@NotNull

白鹭 - 2022-07-20 3113 0 2

一、概述

NullPointerException是一个常见问题。我们可以保护我们的代码的一种方法是在我们的方法参数中添加诸如@NotNull之类的注释。

通过使用NotNull,我们表明如果我们想避免异常,我们绝不能使用null调用我们的方法。然而,就其本身而言,这还不够。让我们来了解一下原因。

2. 方法参数上的@NotNull注解

首先,让我们创建一个具有简单返回String长度的方法的类。

让我们也为我们的参数添加一个@NotNull注解:

public class NotNullMethodParameter {
 public int validateNotNull(@NotNull String data) {
 return data.length();
 }
 }

当我们导入NotNull, w我们应该注意@NotNull注释有几种实现所以,我们需要确保它来自正确的包。

我们将使用javax.validation.constraints包。

现在,让我们创建一个NotNullMethodParameter并使用null参数调用我们的方法:

NotNullMethodParameter notNullMethodParameter = new NotNullMethodParameter();
 notNullMethodParameter.doesNotValidate(null);

尽管我们使用了NotNull注释,但我们得到了NullPointerException

java.lang.NullPointerException

我们的注释无效,因为没有验证器来强制执行它。

3. 添加验证者

因此,让我们添加Hibernate Validator(javax.validation参考实现)来识别我们的@NotNull

除了我们的验证器,我们还需要为它用于呈现消息的表达式语言(EL) 添加一个依赖项:

<dependency>
 <groupId>org.hibernate.validator</groupId>
 <artifactId>hibernate-validator</artifactId>
 <version>6.2.3.Final</version>
 </dependency>

 <dependency>
 <groupId>org.glassfish</groupId>
 <artifactId>javax.el</artifactId>
 <version>3.0.0</version>
 </dependency>

当我们不包含EL 依赖项时,我们会收到一个ValidationException来提醒我们:

javax.validation.ValidationException: HV000183: Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead

有了我们的依赖关系,我们可以强制执行我们的@NotNull注释。

所以,让我们使用默认的ValidatorFactory创建一个验证器:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
 Validator validator = factory.getValidator();

然后,让我们validate我们的论点作为我们带注释的方法的第一行:

validator.validate(myString);

现在,当我们使用null 参数调用我们的方法时,我们的@NotNull被强制执行:

java.lang.IllegalArgumentException: HV000116: The object to be validated must not be null.

这很好,但是必须在每个带注释的方法中添加对我们的验证器的调用会导致大量的样板文件

4. 弹簧靴

幸运的是,我们可以在Spring Boot 应用程序中使用一种更简单的方法。

4.1。春季启动验证

首先,让我们添加Maven 依赖项以使用Spring Boot 进行验证:

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

我们的spring-boot-starter-validation依赖项引入了Spring Boot 和验证所需的一切。这意味着我们可以删除我们之前的Hibernate 和EL 依赖项以保持我们的pom.xml干净。

现在,让我们创建一个Spring 管理的Component确保我们添加了@Validated**注解**。让我们使用validateNotNull方法创建它,该方法接受一个String参数并返回我们数据的长度,并使用NotNull注释我们的参数:

@Component
 @Validated
 public class ValidatingComponent {
 public int validateNotNull(@NotNull String data) {
 return data.length();
 }
 }

最后,让我们使用自动装配的ValidatingComponent创建一个SpringBootTest让我们还添加一个带有null作为方法参数的测试:

@SpringBootTest
 class ValidatingComponentTest {
 @Autowired ValidatingComponent component;

 @Test
 void givenNull_whenValidate_thenConstraintViolationException() {
 assertThrows(ConstraintViolationException.class, () -> component.validate(null));
 }
 }

我们得到的ConstraintViolationException具有我们的参数名称和“不得为空”消息:

javax.validation.ConstraintViolationException: validate.data: must not be null

我们可以在我们的方法约束文章中了解更多关于注释我们的方法的信息。

4.2.一个警告词

虽然这适用于我们的public方法,但让我们看看当我们添加另一个没有注释但调用原始注释方法的方法时会发生什么:

public String callAnnotatedMethod(String data) {
 return validateNotNull(data);
 }

我们的NullPointerException返回。当我们从同一个类中的另一个方法调用带注释的方法时,Spring 不会强制执行NotNull约束。

4.3. Jakarta 和Spring Boot 3.0

在Jakarta 中,验证包名称最近从javax.validation更改为jakarta.validationSpring Boot 3.0 基于Jakarta,因此使用较新的jakarta.validation包。从7.0.* 及更高版本的hibernate-validator版本也是如此。这意味着当我们升级时,我们需要更改我们在验证注释中使用的包名称。

5. 结论

在本文中,我们学习了如何在标准Java 应用程序中对方法参数使用@NotNull注释。我们还学习了如何使用Spring Boot 的@Validated注解来简化我们的Spring Bean 方法参数验证,同时也注意到它的局限性。最后,我们注意到当我们将Spring Boot 项目更新到3.0 时,我们应该期望将我们的javax包更改为jakarta


标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *