问题描述
我的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
}
}
}