在自定义Hibernate validator api的验证器的时候,如果在方法上使用注解校验报如下错误(请参考如下错误信息及代码),如果在Controller的方法上用注解的方式添加验证器CrossParameterValidator,如果不在验证器的实现类上添加@SupportedValidationTarget(value = { ValidationTarget.PARAMETERS })注解,则验证器默认验证方法返回值,所以如果想校验方法的参数的话,则需在验证器的类声明上添加@SupportedValidationTarget(value = { ValidationTarget.PARAMETERS })注解:
HV000030: No validator could be found for constraint 'org.javacms.core.validator.CrossParameterValidator' validating type 'java.lang.String'. Check configuration for 'updateProfile.<return value>'
定义注解:
package org.**.core.validator;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import org.**.core.validator.impl.CrossParameterValidatorImpl;
@Constraint(validatedBy = CrossParameterValidatorImpl.class)
@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface CrossParameterValidator {
String message() default "{password.confirm_password.checking.error}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
验证器代码:
package org.**.core.validator.impl;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Set;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
import org.apache.commons.beanutils.BeanUtils;
import org.**.core.validator.CrossParameterValidator;
@SupportedValidationTarget(value = { ValidationTarget.PARAMETERS })
public class CrossParameterValidatorImpl implements ConstraintValidator<CrossParameterValidator, Object[]> {
private String errorMessage;
public void initialize(CrossParameterValidator constraintAnnotation) {
this.errorMessage = constraintAnnotation.message();
}
public boolean isValid(Object[] value, ConstraintValidatorContext context) {
if (value == null || value.length != 2) {
throw new IllegalArgumentException("There are two args need to be provided for"+this.getClass());
}
if (value[0].equals(value[1])) {
return true;
}
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(this.errorMessage).addConstraintViolation();
return false;
}
}
Controller:
package org.**.controller;
import java.util.HashMap;
import java.util.Map;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.**.core.validator.CrossParameterValidator;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import com.fasterxml.jackson.databind.ObjectMapper;
@Controller
@SuppressWarnings("UnusedDeclaration")
@Validated
public class UserController {
@RequestMapping("/admin/user/profile")
public String editProfile() {
return "/admin/user/profile";
}
@ResponseBody
@RequestMapping("/admin/user/update_profile")
@ResponseStatus(HttpStatus.OK)
@CrossParameterValidator(message = "新密码与确认密码不同")
public String updateProfile(
@RequestParam("newPassword")
String newPassword,
@RequestParam("confirmPassword")
String confirmPassword
) throws Exception {
return "success";
}
}