SpringBoot注解 @Validated

huangapple go评论87阅读模式
英文:

SpringBoot annotation @Validated

问题

验证不会调用ItemDTO字段。
如何使检查对ItemDTO字段起作用?

如果我完全从请求中移除ItemDTO部分,那么NotNull验证将起作用,但不会对内部ItemDTO字段进行验证。

SpringBoot 2.1.9.RELEASE

  1. @RestController
  2. @RequestMapping("/items")
  3. @RequiredArgsConstructor
  4. public class ItemController {
  5. private final ItemLimitService itemLimitService;
  6. @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  7. public ResponseEntity<ItemLimitDTO> create(@Validated(New.class) @RequestBody ItemLimitDTO limitDTO) {
  8. ItemLimit limit = itemLimitService.create(limitDTO);
  9. return ResponseEntity.status(HttpStatus.CREATED).body(limit);
  10. }
  11. }
  12. public class ItemLimitDTO {
  13. @Null(groups = {New.class})
  14. @NotNull(groups = {Exist.class})
  15. private Integer id;
  16. @PositiveOrZero(groups = {New.class, Exist.class})
  17. private Integer value;
  18. @NotNull(groups = {New.class, Exist.class})
  19. private ItemDTO item;
  20. }
  21. public class ItemDTO {
  22. @Null(groups = {New.class})
  23. @NotNull(groups = {Exist.class})
  24. private Integer id;
  25. @PositiveOrZero(groups = {New.class, Exist.class})
  26. private Integer value;
  27. }
英文:

Validation is not called for ItemDTO fields.
How do I make the check work for ItemDTO fields?

If I completely remove the ItemDTO section from the request, then NotNull validation will work, but validation is not called for internal ItemDTO fields.

SpringBoot 2.1.9.RELEASE

  1. @RestController
  2. @RequestMapping(&quot;/items&quot;)
  3. @RequiredArgsConstructor
  4. public class ItemController {
  5. private final ItemLimitService itemLimitService;
  6. @PostMapping(value = &quot;&quot;, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
  7. public ResponseEntity&lt;ItemLimitDTO&gt; create(@Validated(New.class) @RequestBody ItemLimitDTO limitDTO) {
  8. ItemLimit limit = itemLimitService.create(limitDTO);
  9. return ResponseEntity.status(HttpStatus.CREATED).body(limit);
  10. }
  11. }
  12. public class ItemLimitDTO {
  13. @Null(groups = {New.class})
  14. @NotNull(groups = {Exist.class})
  15. private Integer id;
  16. @PositiveOrZero(groups = {New.class, Exist.class})
  17. private Integer value;
  18. @NotNull(groups = {New.class, Exist.class})
  19. private ItemDTO item;
  20. }
  21. public class ItemDTO {
  22. @Null(groups = {New.class})
  23. @NotNull(groups = {Exist.class})
  24. private Integer id;
  25. @PositiveOrZero(groups = {New.class, Exist.class})
  26. private Integer value;
  27. }

答案1

得分: 1

尝试在方法级别使用@Validated(New.class),并在方法参数本身上使用@Valid

  1. @Validated(New.class)
  2. @PostMapping(...)
  3. public ResponseEntity<ItemLimitDTO> create(@Valid @RequestBody ItemLimitDTO limitDTO) {
  4. // ...
  5. }
英文:

try using @Validated(New.class) at the level of the method and @Valid for the method argument itself:

  1. @Validated(New.class)
  2. @PostMapping(...)
  3. public ResponseEntity&lt;ItemLimitDTO&gt; create(@Valid @RequestBody ItemLimitDTO limitDTO) {
  4. // ...
  5. }

答案2

得分: 1

你需要在 ItemDTO 上添加 @Valid 注解,以启用级联验证,如Hibernate验证器文档所述:

对象图的验证是递归的,即如果标记为级联验证的引用指向一个对象,该对象本身具有用 @Valid 注解的属性,验证引擎也将跟随这些引用进行验证。验证引擎将确保在级联验证期间不会发生无限循环,例如,如果两个对象互相引用。

所以更改如下应该解决您的问题:

  1. public class ItemLimitDTO {
  2. @Null(groups = {New.class})
  3. @NotNull(groups = {Exist.class})
  4. private Integer id;
  5. @PositiveOrZero(groups = {New.class, Exist.class})
  6. private Integer value;
  7. @Valid
  8. @NotNull(groups = {New.class, Exist.class})
  9. private ItemDTO item;
  10. }
英文:

You have to annotate @Valid on ItemDTO to enable cascade validation which is mentioned by the hibernate validator documentation as follows :

> The validation of object graphs is recursive, i.e. if a reference
> marked for cascaded validation points to an object which itself has
> properties annotated with @Valid, these references will be followed up
> by the validation engine as well. The validation engine will ensure
> that no infinite loops occur during cascaded validation, for example
> if two objects hold references to each other.

So change to the following should fix your problem :

  1. public class ItemLimitDTO {
  2. @Null(groups = {New.class})
  3. @NotNull(groups = {Exist.class})
  4. private Integer id;
  5. @PositiveOrZero(groups = {New.class, Exist.class})
  6. private Integer value;
  7. @Valid
  8. @NotNull(groups = {New.class, Exist.class})
  9. private ItemDTO item;
  10. }

huangapple
  • 本文由 发表于 2023年3月3日 22:46:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628523.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定