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

qfe3c7zg  于 2022-11-14  发布在  Spring
关注(0)|答案(2)|浏览(142)

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

提前致谢!

zrfyljdw

zrfyljdw1#

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

@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{};
}

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

public class OrderValidator implements ConstraintValidator<OrderId, String> {

    @Autowired
    private OrderRepository repository;

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

    }
}
r9f1avp5

r9f1avp52#

我建议尝试一种不同的方法。尽量不要在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
       }

    }
}

相关问题