如何在请求正文 Spring Boot Rest Controller 中指定订单验证
Posted
技术标签:
【中文标题】如何在请求正文 Spring Boot Rest Controller 中指定订单验证【英文标题】:How to specify order validation in Request body Spring Boot Rest Controller 【发布时间】:2022-01-22 18:31:33 【问题描述】:所以我在Spring Boot
中有一个Rest Controller
,对于端点,我需要验证它的Request Body
。
控制器:
@RestController
@Validated
@RequestMapping("/my_endpoint")
public class WorkflowController
@PostMapping(value = "/blablabla/", consumes = MediaType.APPLICATION_JSON_VALUE)
public List<Object> createDisconnectRequestRest(@RequestBody List<@CustomValidator @Valid RequestObj> dtos) // here at the validators is the question
... //nevermind
return null;
请求对象:
@Data
public class RequestObj
private String comment;
@NotNull // this @NotNull annotation validator is triggered AFTER the custom validator is done. I want this to be first validated and then the custom validator should take place
private List<Long> ids = new ArrayList<>();
@Target(FIELD, TYPE_USE)
@Retention(RUNTIME)
@Constraint(validatedBy = CustomValidator.class)
@Documented
public @interface ValidRequest
String message() default "Invalid request";
Class<?>[] groups() default ;
Class<? extends Payload>[] payload() default ;
自定义验证器:
public class CustomValidator implements ConstraintValidator<ValidRequest, RequestObj>
// repositories, constructor
@Override
public boolean isValid(RequestObj request, ConstraintValidatorContext constraintValidatorContext)
myRepository.findAllById(request.getIds()); // I want the @NotNull annotation validate the object before this custom validator
return true;
这是问题:
要触发的第一个是 CustomValidator,然后正在验证 RequestObj
。换句话说,验证从@CustomValidator
注释开始,然后是@Valid
注释。我希望第一个被触发的是@Valid
注释(所以@NotNull
注释将首先验证对象)然后@CustomValidator
应该完成它的工作。例如,如果 body 字段 ids
为 NULL,我希望 @CustomValidator
甚至无法启动,因为验证已经失败。
【问题讨论】:
您是否尝试过更改注释的顺序? 是的,没用。 【参考方案1】:这可能是因为您在类级别应用了@CustomValidator
注释,并且类在属性之前首先加载,这可能是您看到此顺序或执行的原因。
你有几个选择:
1- 在特定属性级别应用此 @CustomValidator
,
2- 将您的CustomValidator
设置为@Component
,并从类级别中删除@CustomValidator
注释。然后在您的控制器方法中执行以下操作:
@Autowired
private CustomValidator customValidator;
@PostMapping(value = "/blablabla/", consumes = MediaType.APPLICATION_JSON_VALUE)
public List<Object> createDisconnectRequestRest(@RequestBody List<@Valid RequestObj> dtos) // here at the validators is the question
customValidator.validate(xyz);
--- 未经检验的理论 ---
您能否尝试更改在方法级别应用的注释的顺序,看看是否有所不同:
@PostMapping(value = "/blablabla/", consumes = MediaType.APPLICATION_JSON_VALUE)
public List<Object> createDisconnectRequestRest(@RequestBody List<@Valid @CustomValidator RequestObj> dtos) // here at the validators is the question
... //nevermind
return null;
【讨论】:
1.在特定属性级别添加@CustomValidator
不是一种选择。我正在验证不同类型的属性组合 2. 更改顺序也不起作用。 3. 我想避免在控制器方法内部进行验证的解决方法
我在@GroupSequence
注释中找到了与此主题相关的内容。我正在阅读它,如果我找到任何解决方案,我会更新主题
@GroupSequence
用于对注释进行分组,在您的情况下,您正在查看 Validators 的优先顺序,所以我怀疑它是否会起作用。以上是关于如何在请求正文 Spring Boot Rest Controller 中指定订单验证的主要内容,如果未能解决你的问题,请参考以下文章
如何在 spring-boot Web 客户端中发送请求正文?
Spring Data Rest:如何使用请求正文发送多部分文件
如何在 Spring Boot Rest 调用中传递 Date 类型的值?
如何在 Spring Boot 服务应用程序中的 REST 服务调用之间按原样传递请求参数?
如何在 Spring REST 控制器中获取原始 JSON 正文?
ControllerAdvice 的异常处理程序在使用 Spring Boot 的 Rest API 获取请求中不起作用。如何解决?