什么是约束验证点@Null?

What is point of constraint validation @Null?

我正在检查 list of available constraints in javax.validation package and I noticed that there is an annotation @Null 强制该字段为空。

如果我已经知道它应该为空,我不明白将它添加到我的字段中有什么意义。

例如看这个 class:

public class MyClass{

    @NotNull
    private String myString1;

    @Null
    private String myString2;

    // getter setters...
}

@NotNull完全有道理。我不希望 myString1 为空。但是 @Null 使 myString2 无用。拥有一个应该始终为空的字段有什么意义。

引用this文档,这里是空注解的要求。

At first sight using null annotations for API specifications in the vein of Design by Contract only means that the signatures of all API methods should be fully annotated, i.e., except for primitive types like int each parameter and each method return type should be marked as either @NonNull or @Nullable. Since this would mean to insert very many null annotations, it is good to know that in well-designed code (especially API methods), @NonNull is significantly more frequent than @Nullable. Thus the number of annotations can be reduced by declaring @NonNull as the default, using a @NonNullByDefault annotation at the package level.

然而,话虽如此,是的,你是对的,@Null 没有多大意义,在设计良好的适当代码中,@NotNull 更重要,也更频繁。 @Null 或@Nullable 的存在只是为了表示此处需要空值,并有助于防止调用者和被调用者对空值进行冗余检查。希望这有帮助。

您可能希望结合使用 @Null 和 "Validation Group" 以仅在某些情况下验证空约束。

Good explanation and example on validation groups provided by Hibernate

您将验证组定义为简单接口

public interface FirstSave {}

然后在约束中使用它

public class MyClass {

    @Null(groups = FirstSave.class)
    private LocalDate lastUpdate;
}

那么如果lastUpdate不是null,调用validator.validate(myClassInstance)不会产生约束违反(使用默认组),但调用 validator.validate(myClassInstance, FirstSave.class) 将。

您还可以提供关于如何使用注释的自己的实现,即我已经看到验证方法被注释为 @Null,其中方法返回的 null 意味着一切没关系。在后台可能有关于如果注释方法返回非空结果该怎么做的自定义实现,但我没有深入代码...

@Null是一个很重要的注解。这不是没有用的。让我展示一个常见的用例。比如说,有一个自动生成 Id 的 DAO(实体)对象。

如果您对 DTO 和 DAO 使用单独的 类,@GetMapping returns DTO 列表没有问题。另一方面,用于添加新元素的 @PostMapping 要求输入 DTO 不得包含 Id 字段,即使存在,它也必须为 null 或未定义。 这样的输入在与 DTO 对象相互转换时,要求 Id 必须为空。 为此,@Null是唯一的选择

@PutMapping 期望 id 不能为空,因此当我们期望更新发生在单个对象上时,id 字段需要 @NotNull

@DeleteMapping 仅需要整数 Id ,仅当我们要删除具有已知 Id 的对象时。

有另类的复杂案例,通常不处理但有道理

@GetMapping 可用于任何提供的字段,但如果提供了 Id 以外的任何字段,则 Id 必须为空。如果提供了 Id,则所有其他必须为空。

还有一个复杂的@PutMapping要求, 其中提供了部分信息以供更新和预期的剩余字段为旧值。这里更新了非空字段。

另一个注释@DeleteMapping用于删除或删除。如果计算为空白,可以用@Null约束来实现。

通常的 CRUD 操作过于简单但不适合实际期望的用例。

所有这些混合需求都可以分组列出。 并且可以通过具有单独标记接口的组属性提供约束 @Validated 可以根据要求应用。