我想验证我的控制器中的请求参数之一。请求参数应来自给定值列表之一,如果不是,则应引发错误。在下面的代码中,我希望请求参数 orderBy 来自 @ValuesAllowed 中存在的值列表。
@RestController
@RequestMapping("/api/opportunity")
@Api(value = "Opportunity APIs")
@ValuesAllowed(propName = "orderBy", values = { "OpportunityCount", "OpportunityPublishedCount", "ApplicationCount",
"ApplicationsApprovedCount" })
public class OpportunityController {
@GetMapping("/vendors/list")
@ApiOperation(value = "Get all vendors")
public ResultWrapperDTO getVendorpage(@RequestParam(required = false) String term,
@RequestParam(required = false) Integer page, @RequestParam(required = false) Integer size,
@RequestParam(required = false) String orderBy, @RequestParam(required = false) String sortDir) {
我编写了一个自定义 bean 验证器,但不知何故这不起作用。即使为查询参数传递任何随机值,它也不会验证并引发错误。
@Repeatable(ValuesAllowedMultiple.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {ValuesAllowedValidator.class})
public @interface ValuesAllowed {
String message() default "Field value should be from list of ";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String propName();
String[] values();
}
public class ValuesAllowedValidator implements ConstraintValidator<ValuesAllowed, Object> {
private String propName;
private String message;
private String[] values;
@Override
public void initialize(ValuesAllowed requiredIfChecked) {
propName = requiredIfChecked.propName();
message = requiredIfChecked.message();
values = requiredIfChecked.values();
}
@Override
public boolean isValid(Object object, ConstraintValidatorContext context) {
Boolean valid = true;
try {
Object checkedValue = BeanUtils.getProperty(object, propName);
if (checkedValue != null) {
valid = Arrays.asList(values).contains(checkedValue.toString().toLowerCase());
}
if (!valid) {
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message.concat(Arrays.toString(values)))
.addPropertyNode(propName).addConstraintViolation();
}
} catch (IllegalAccessException e) {
log.error("Accessor method is not available for class : {}, exception : {}", object.getClass().getName(), e);
return false;
} catch (NoSuchMethodException e) {
log.error("Field or method is not present on class : {}, exception : {}", object.getClass().getName(), e);
return false;
} catch (InvocationTargetException e) {
log.error("An exception occurred while accessing class : {}, exception : {}", object.getClass().getName(), e);
return false;
}
return valid;
}
}
原文由 Ladu anand 发布,翻译遵循 CC BY-SA 4.0 许可协议
案例1:如果根本没有触发ValuesAllowed注解,可能是因为没有用@Validated注解控制器。
情况 2:如果它被触发并抛出错误,可能是因为
BeanUtils.getProperty
没有解析属性并抛出异常。如果上述解决方案不起作用,您可以尝试将注解移至方法级别并更新 Validator 以使用
OrderBy
参数的有效值列表。这对我有用。下面是示例代码。