SpringBoot注解 @Validated

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

SpringBoot annotation @Validated

问题

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

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

SpringBoot 2.1.9.RELEASE

@RestController
@RequestMapping("/items")
@RequiredArgsConstructor
public class ItemController {
    
    private final ItemLimitService itemLimitService;

    @PostMapping(value = "", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public ResponseEntity<ItemLimitDTO> create(@Validated(New.class) @RequestBody ItemLimitDTO limitDTO) {
        ItemLimit limit = itemLimitService.create(limitDTO);
        return ResponseEntity.status(HttpStatus.CREATED).body(limit);
    }
    
}

public class ItemLimitDTO {

    @Null(groups = {New.class})
    @NotNull(groups = {Exist.class})
    private Integer id;

    @PositiveOrZero(groups = {New.class, Exist.class})
    private Integer value;

    @NotNull(groups = {New.class, Exist.class})
    private ItemDTO item;

}

public class ItemDTO {

    @Null(groups = {New.class})
    @NotNull(groups = {Exist.class})
    private Integer id;

    @PositiveOrZero(groups = {New.class, Exist.class})
    private Integer value;

}
英文:

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

    @RestController
    @RequestMapping(&quot;/items&quot;)
    @RequiredArgsConstructor
    public class ItemController {
        
        private final ItemLimitService itemLimitService;

        @PostMapping(value = &quot;&quot;, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
        public ResponseEntity&lt;ItemLimitDTO&gt; create(@Validated(New.class) @RequestBody ItemLimitDTO limitDTO) {
            ItemLimit limit = itemLimitService.create(limitDTO);
            return ResponseEntity.status(HttpStatus.CREATED).body(limit);
        }
        
    }

    public class ItemLimitDTO {

        @Null(groups = {New.class})
        @NotNull(groups = {Exist.class})
        private Integer id;

        @PositiveOrZero(groups = {New.class, Exist.class})
        private Integer value;

        @NotNull(groups = {New.class, Exist.class})
        private ItemDTO item;

    }

    public class ItemDTO {

        @Null(groups = {New.class})
        @NotNull(groups = {Exist.class})
        private Integer id;

        @PositiveOrZero(groups = {New.class, Exist.class})
        private Integer value;

    }

答案1

得分: 1

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

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

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

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

答案2

得分: 1

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

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

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

public class ItemLimitDTO {

    @Null(groups = {New.class})
    @NotNull(groups = {Exist.class})
    private Integer id;

    @PositiveOrZero(groups = {New.class, Exist.class})
    private Integer value;

    @Valid
    @NotNull(groups = {New.class, Exist.class})
    private ItemDTO item;

}
英文:

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 :

public class ItemLimitDTO {

        @Null(groups = {New.class})
        @NotNull(groups = {Exist.class})
        private Integer id;

        @PositiveOrZero(groups = {New.class, Exist.class})
        private Integer value;

        @Valid
        @NotNull(groups = {New.class, Exist.class})
        private ItemDTO item;

    }


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:

确定