如何首先验证Spring @PathVariable属性?

问题描述

我的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) {
        //...
    }
}

预先感谢!

解决方法

您可以编写自定义注释和验证器以验证@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是否存在于数据库中或其他任何验证中)

public class OrderValidator implements ConstraintValidator<OrderId,String> {

    @Autowired
    private OrderRepository repository;

    @Override
    public boolean isValid(String value,ConstraintValidatorContext context) {
            return (repository.existsByPeriod(value));

    }
}
,

我建议尝试其他方法。尽量不要在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
       }

    }
}