【问题标题】:How to validate Spring @PathVariable properties first?如何首先验证 Spring @PathVariable 属性?
【发布时间】:2020-11-12 04:37:15
【问题描述】:

我的 Spring Controller 类中有以下 PUT 方法。有一个用@PathVariable注解的参数。还有一个用@RequestBody@Valid注解的参数。问题是 RequestBody 首先得到验证,并且该方法在出现异常时返回。但我希望首先验证@Pathvariable,并在出现异常时返回。

@RestController
@Validated
@RequestMapping(value = "/v1/order", produces = MediaType.APPLICATION_JSON_VALUE)
public class OrderMappingController {

    @PutMapping(value = "/{id}/order-mapping", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> UpdateOrderMapping(@PathVariable(value = "id") @NotBlank(message = "InvalidID")
                                                @ValidOrderId String id,
                                                @RequestBody @Valid OrderMappingRequest request) {
        //...
    }
}

提前致谢!

【问题讨论】:

    标签: spring spring-boot spring-mvc bean-validation


    【解决方案1】:

    您可以编写自定义注解和验证器来验证@Pathvariable

    @RestController
        @Validated
        @RequestMapping(value = "/v1/order", produces = MediaType.APPLICATION_JSON_VALUE)
        public class OrderMappingController {
        
                @PutMapping(value = "/{id}/order-mapping", produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
                public ResponseEntity<?> UpdateOrderMapping(@PathVariable(value = "id") @OrderId  String id,
                                                            @RequestBody @Valid OrderMappingRequest request) {
                    //...
                }
            }
    

    创建可以使用自定义验证器类 OrderIdValidator 进行验证的自定义注解 OrderId

    @Constraint(validatedBy = OrderIdValidator.class)
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.FIELD, ElementType.METHOD,PARAMETER })
    public @interface OrderId{
        public String message() default "order id not found ";
        public Class<?>[] groups() default {};
        public Class<? extends Payload>[] payload() default{};
    }
    

    然后您可以编写自定义验证器类,它可以检查 id 是否存在于 db 中或任何其他验证中的业务逻辑

    public class OrderValidator implements ConstraintValidator<OrderId, String> {
    
        @Autowired
        private OrderRepository repository;
    
        @Override
        public boolean isValid(String value, ConstraintValidatorContext context) {
                return (repository.existsByPeriod(value));
    
        }
    }
    

    【讨论】:

    • 这正是我所做的。但我需要先进行 Pathvariable 验证。有没有办法先验证 OrderId 并向客户端返回错误消息?
    【解决方案2】:

    我建议尝试不同的方法。尽量不要在 OrderMappingRequest 上注释 @Valid,然后为您的 OrderMappingRequest bean 实现自定义 org.springframework.validation.Validator,然后将其注入并在您的 OrderMappingController#UpdateOrderMapping 方法中调用。

    public class OrderMappingController {
    
        @Autowired
        private OrderMappingRequestValidator validator
    
        @PutMapping("/{id}/order-mapping")
        public ResponseEntity<?> UpdateOrderMapping(@PathVariable 
                                                    @NotBlank(message = "InvalidID")
                                                    @ValidOrderId String id,
                                                    @RequestBody OrderMappingRequest request,
                                                    BindingResult result) {
            
           validator.validate(request, result);
    
           if(result.hasErrors()){
              ... do stuff or throw
           }
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-09
      • 2023-03-05
      • 2016-05-26
      • 2018-04-06
      • 2011-02-01
      • 2019-10-30
      • 2015-01-11
      • 1970-01-01
      相关资源
      最近更新 更多