下面列出了怎么用javax.validation.executable.ExecutableValidator的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Validates the Bean Validation constraints specified at the parameters and/or
* return value of the intercepted method.
*
* @param ctx The context of the intercepted method invocation.
* @param customValidator Custom Validator
*
* @return The result of the method invocation.
*
* @throws Exception Any exception caused by the intercepted method invocation.
* A {@link ConstraintViolationException} in case at least one
* constraint violation occurred either during parameter or
* return value validation.
*/
protected Object validateMethodInvocation(InvocationContext ctx) throws Exception {
ExecutableValidator executableValidator = validator.forExecutables();
Set<ConstraintViolation<Object>> violations = executableValidator.validateParameters(ctx.getTarget(),
ctx.getMethod(), ctx.getParameters());
if (!violations.isEmpty()) {
throw new ConstraintViolationException(getMessage(ctx.getMethod(), ctx.getParameters(), violations),
violations);
}
Object result = ctx.proceed();
violations = executableValidator.validateReturnValue(ctx.getTarget(), ctx.getMethod(), result);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(getMessage(ctx.getMethod(), ctx.getParameters(), violations),
violations);
}
return result;
}
/**
* Validates the Bean Validation constraints specified at the parameters and/or
* return value of the intercepted constructor.
*
* @param ctx The context of the intercepted constructor invocation.
*
* @throws Exception Any exception caused by the intercepted constructor
* invocation. A {@link ConstraintViolationException} in case
* at least one constraint violation occurred either during
* parameter or return value validation.
*/
protected void validateConstructorInvocation(InvocationContext ctx) throws Exception {
ExecutableValidator executableValidator = validator.forExecutables();
Set<? extends ConstraintViolation<?>> violations = executableValidator
.validateConstructorParameters(ctx.getConstructor(), ctx.getParameters());
if (!violations.isEmpty()) {
throw new ConstraintViolationException(getMessage(ctx.getConstructor(), ctx.getParameters(), violations),
violations);
}
ctx.proceed();
Object createdObject = ctx.getTarget();
violations = validator.forExecutables().validateConstructorReturnValue(ctx.getConstructor(), createdObject);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(getMessage(ctx.getConstructor(), ctx.getParameters(), violations),
violations);
}
}
/**
*
* @param invocation
* @return
* @throws ConstraintViolationException incase of any constraints
* defined on method parameters are violated.
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
if (skipMethod(invocation)) {
return invocation.proceed();
}
ExecutableValidator executableValidator = validatorProvider.get().forExecutables();
Set<ConstraintViolation<Object>> result = executableValidator.validateParameters(
invocation.getThis(), invocation.getMethod(), invocation.getArguments());
if (!result.isEmpty()) {
throw new ConstraintViolationException(result);
}
return invocation.proceed();
}
@Override
protected void configure() {
final GuiceConstraintValidatorFactory constraintValidatorFactory = new GuiceConstraintValidatorFactory();
requestInjection(constraintValidatorFactory);
/* Overriding just constraints factory to allow them use guice injections */
final Validator validator = factory.usingContext()
.constraintValidatorFactory(constraintValidatorFactory)
.getValidator();
bind(Validator.class).toInstance(validator);
bind(ExecutableValidator.class).toInstance(validator.forExecutables());
// NOTE bound factory is not aware of guice! because it use default ConstraintValidatorFactory
bind(ValidatorFactory.class).toInstance(factory);
bind(ValidationContext.class);
bindConstant().annotatedWith(Names.named("guice.validator.addDefaultGroup")).to(addDefaultGroup);
final ValidationGroupInterceptor groupInterceptor = new ValidationGroupInterceptor();
requestInjection(groupInterceptor);
configureGroupsAop(groupInterceptor);
final ValidationMethodInterceptor interceptor = new ValidationMethodInterceptor();
requestInjection(interceptor);
configureAop(interceptor);
}
@Test
public void testMethodParameters() throws NoSuchMethodException {
ExecutableValidator executableValidator = validator.forExecutables();
Method method = RentalStation.class.getMethod("rentCar", String.class, Date.class,
Integer.TYPE);
RentalStation station = new RentalStation("hertz", "");
Set<ConstraintViolation<RentalStation>> violations = executableValidator.validateParameters(
station, method, new Object[]{"Clement", new Date(System.currentTimeMillis() + 10000), 1});
assertThat(violations.size()).isEqualTo(0);
violations = executableValidator.validateParameters(
station, method, new Object[]{"Clement", new Date(System.currentTimeMillis() - 10000), 1});
assertThat(violations.size()).isEqualTo(1);
violations = executableValidator.validateParameters(
station, method, new Object[]{"Clement", new Date(System.currentTimeMillis() - 10000), 0});
assertThat(violations.size()).isEqualTo(2);
violations = executableValidator.validateParameters(
station, method, new Object[]{null, new Date(System.currentTimeMillis() - 10000), 0});
assertThat(violations.size()).isEqualTo(3);
}
@Test
public void testMethodParameters() throws NoSuchMethodException {
ExecutableValidator executableValidator = validator.forExecutables();
Method method = RentalStation.class.getMethod("rentCar", String.class, Date.class,
Integer.TYPE);
RentalStation station = new RentalStation("hertz", "");
Set<ConstraintViolation<RentalStation>> violations = executableValidator.validateParameters(
station, method, new Object[]{"Clement", new Date(System.currentTimeMillis() + 10000), 1});
assertThat(violations.size()).isEqualTo(0);
violations = executableValidator.validateParameters(
station, method, new Object[]{"Clement", new Date(System.currentTimeMillis() - 10000), 1});
assertThat(violations.size()).isEqualTo(1);
violations = executableValidator.validateParameters(
station, method, new Object[]{"Clement", new Date(System.currentTimeMillis() - 10000), 0});
assertThat(violations.size()).isEqualTo(2);
violations = executableValidator.validateParameters(
station, method, new Object[]{null, new Date(System.currentTimeMillis() - 10000), 0});
assertThat(violations.size()).isEqualTo(3);
}
@Override
@SuppressWarnings("unchecked")
public Object invoke(MethodInvocation invocation) throws Throwable {
// Avoid Validator invocation on FactoryBean.getObjectType/isSingleton
if (isFactoryBeanMetadataMethod(invocation.getMethod())) {
return invocation.proceed();
}
Class<?>[] groups = determineValidationGroups(invocation);
// Standard Bean Validation 1.1 API
ExecutableValidator execVal = this.validator.forExecutables();
Method methodToValidate = invocation.getMethod();
Set<ConstraintViolation<Object>> result;
try {
result = execVal.validateParameters(
invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
}
catch (IllegalArgumentException ex) {
// Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011
// Let's try to find the bridged method on the implementation class...
methodToValidate = BridgeMethodResolver.findBridgedMethod(
ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass()));
result = execVal.validateParameters(
invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
}
if (!result.isEmpty()) {
throw new ConstraintViolationException(result);
}
Object returnValue = invocation.proceed();
result = execVal.validateReturnValue(invocation.getThis(), methodToValidate, returnValue, groups);
if (!result.isEmpty()) {
throw new ConstraintViolationException(result);
}
return returnValue;
}
@Override
@SuppressWarnings("unchecked")
public Object invoke(MethodInvocation invocation) throws Throwable {
// Avoid Validator invocation on FactoryBean.getObjectType/isSingleton
if (isFactoryBeanMetadataMethod(invocation.getMethod())) {
return invocation.proceed();
}
Class<?>[] groups = determineValidationGroups(invocation);
// Standard Bean Validation 1.1 API
ExecutableValidator execVal = this.validator.forExecutables();
Method methodToValidate = invocation.getMethod();
Set<ConstraintViolation<Object>> result;
try {
result = execVal.validateParameters(
invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
}
catch (IllegalArgumentException ex) {
// Probably a generic type mismatch between interface and impl as reported in SPR-12237 / HV-1011
// Let's try to find the bridged method on the implementation class...
methodToValidate = BridgeMethodResolver.findBridgedMethod(
ClassUtils.getMostSpecificMethod(invocation.getMethod(), invocation.getThis().getClass()));
result = execVal.validateParameters(
invocation.getThis(), methodToValidate, invocation.getArguments(), groups);
}
if (!result.isEmpty()) {
throw new ConstraintViolationException(result);
}
Object returnValue = invocation.proceed();
result = execVal.validateReturnValue(invocation.getThis(), methodToValidate, returnValue, groups);
if (!result.isEmpty()) {
throw new ConstraintViolationException(result);
}
return returnValue;
}
@AroundInvoke
public Object validateMethodInvocation(InvocationContext ctx) throws Exception {
Object resource = ctx.getTarget();
Method method = ctx.getMethod();
log.log(Level.FINE, "Starting validation for controller method: {0}#{1}", new Object[]{
resource.getClass().getName(), method.getName()
});
Validator validator = validatorFactory.getValidator();
ExecutableValidator executableValidator = validator.forExecutables();
// validate controller property parameters
processViolations(ctx,
validator.validate(resource)
);
// validate controller method parameters
processViolations(ctx,
executableValidator.validateParameters(resource, method, ctx.getParameters())
);
// execute method
Object result = ctx.proceed();
// TODO: Does this make sense? Nobody will be able to handle these. Remove?
processViolations(ctx,
executableValidator.validateReturnValue(resource, method, result)
);
return result;
}
private static void validate(Method method, RouteDefinition definition, Validator validator, Object toInvoke, Object[] args) {
// check method params first (if any)
if (validator != null && args != null) {
ExecutableValidator executableValidator = validator.forExecutables();
Set<ConstraintViolation<Object>> result = executableValidator.validateParameters(toInvoke, method, args);
if (result != null && result.size() > 0) {
throw new ConstraintException(definition, result);
}
}
}
private static void validateResult(Object result, Method method, RouteDefinition definition, Validator validator, Object toInvoke) {
if (validator != null) {
ExecutableValidator executableValidator = validator.forExecutables();
Set<ConstraintViolation<Object>> validationResult = executableValidator.validateReturnValue(toInvoke, method, result);
if (validationResult != null && validationResult.size() > 0) {
throw new ConstraintException(definition, validationResult);
}
}
}
@Test
public void testWorkflowTaskTestSetType() throws NoSuchMethodException {
WorkflowTask workflowTask = createSampleWorkflowTask();
Method method = WorkflowTask.class.getMethod("setType", String.class);
Object[] parameterValues = {""};
ExecutableValidator executableValidator = validator.forExecutables();
Set<ConstraintViolation<Object>> result = executableValidator.validateParameters(workflowTask, method, parameterValues);
assertEquals(1, result.size());
assertEquals(result.iterator().next().getMessage(), "WorkTask type cannot be null or empty");
}
@AroundInvoke
public Object validateMethodInvocation(InvocationContext ctx) throws Exception {
Object resource = ctx.getTarget();
Method method = ctx.getMethod();
log.log(Level.FINE, "Starting validation for controller method: {0}#{1}", new Object[]{
resource.getClass().getName(), method.getName()
});
Validator validator = validatorFactory.getValidator();
ExecutableValidator executableValidator = validator.forExecutables();
// validate controller property parameters
processViolations(ctx,
validator.validate(resource)
);
// validate controller method parameters
processViolations(ctx,
executableValidator.validateParameters(resource, method, ctx.getParameters())
);
// execute method
Object result = ctx.proceed();
// TODO: Does this make sense? Nobody will be able to handle these. Remove?
processViolations(ctx,
executableValidator.validateReturnValue(resource, method, result)
);
return result;
}
public <T> void validate(final Method method, final Object[] arguments, final T instance) {
if (validator == null) {
log.warn("Bean Validation provider could not be found, no validation will be performed");
return;
}
ExecutableValidator methodValidator = validator.forExecutables();
Set<ConstraintViolation<T>> violations = methodValidator.validateParameters(instance,
method, arguments);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
public <T> void validate(final Method method, final Object[] arguments, final T instance) {
if (validator == null) {
log.warn("Bean Validation provider could not be found, no validation will be performed");
return;
}
ExecutableValidator methodValidator = validator.forExecutables();
Set<ConstraintViolation<T>> violations = methodValidator.validateParameters(instance,
method, arguments);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
private ExecutableValidator executableValidator() {
if (null == executableValidator) {
synchronized (this) {
if (null == executableValidator) {
validator = Act.getInstance(Validator.class);
executableValidator = validator.forExecutables();
}
}
}
return executableValidator;
}
public <T> void validate(final Method method, final Object[] arguments, final T instance) {
if (validator == null) {
log.warn("Bean Validation provider could not be found, no validation will be performed");
return;
}
ExecutableValidator methodValidator = validator.forExecutables();
Set<ConstraintViolation<T>> violations = methodValidator.validateParameters(instance,
method, arguments);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
ExecutableValidator executableValidator = validatorFactory.getValidator().forExecutables();
if (executableValidator == null) {
throw SeedException.createNew(ValidationErrorCode.DYNAMIC_VALIDATION_IS_NOT_SUPPORTED);
}
validateParameters(invocation, executableValidator);
Object returnValue = invocation.proceed();
validateReturnValue(invocation, executableValidator, returnValue);
return returnValue;
}
private void validateParameters(MethodInvocation invocation, ExecutableValidator executableValidator) {
// validation by interception is always done with the default group
Set<ConstraintViolation<Object>> constraintViolations = executableValidator.validateParameters(
invocation.getThis(),
invocation.getMethod(),
invocation.getArguments()
);
if (!constraintViolations.isEmpty()) {
throw new VerboseConstraintViolationException(constraintViolations);
}
}
private void validateReturnValue(MethodInvocation invocation, ExecutableValidator executableValidator,
Object returnValue) {
Set<ConstraintViolation<Object>> constraintViolations = executableValidator.validateReturnValue(
invocation.getThis(),
invocation.getMethod(),
returnValue
/*, groups*/
);
if (!constraintViolations.isEmpty()) {
throw new VerboseConstraintViolationException(constraintViolations);
}
}
public< T > void validateParameters(final T instance, final Method method, final Object[] arguments) {
final ExecutableValidator methodValidator = getExecutableValidator();
final Set< ConstraintViolation< T > > violations = methodValidator.validateParameters(instance,
method, arguments);
if (!violations.isEmpty()) {
throw new ConstraintViolationException(violations);
}
}
public< T > void validateReturnValue(final T instance, final Method method, final Object returnValue) {
final ExecutableValidator methodValidator = getExecutableValidator();
final Set<ConstraintViolation< T > > violations = methodValidator.validateReturnValue(instance,
method, returnValue);
if (!violations.isEmpty()) {
throw new ResponseConstraintViolationException(violations);
}
}
public static ValidationConstraints of(final Class<?> componentClass) {
final ClassValidationData data = new ClassValidationData(componentClass);
if (data.getJwtConstraints().size() == 0) return null;
final Class<?> constraintsClazz = new ClassValidationGenerator(data)
.generate()
.stream()
.filter(aClass -> aClass.getName().endsWith("JwtConstraints"))
.findFirst()
.orElseThrow(MissingConstraintsException::new);
final Map<Method, Method> mapping = new HashMap<>();
Stream.of(constraintsClazz.getMethods())
.filter(method -> method.isAnnotationPresent(Generated.class))
.forEach(method -> mapping.put(resolve(componentClass, method), method)
);
final Object instance;
try {
instance = constraintsClazz.newInstance();
} catch (Exception e) {
throw new ConstraintsClassInstantiationException(constraintsClazz, e);
}
final ExecutableValidator executableValidator = Validation.buildDefaultValidatorFactory()
.getValidator()
.forExecutables();
return new ValidationConstraints(instance, mapping, executableValidator);
}
@Test
public void testConstructorParameters() throws NoSuchMethodException {
ExecutableValidator executableValidator = validator.forExecutables();
Constructor<RentalStation> constructor = RentalStation.class.getConstructor(String.class, String.class);
Set<ConstraintViolation<RentalStation>> violations = executableValidator.validateConstructorParameters
(constructor, new Object[] {"Hertz", ""});
assertThat(violations.size()).isEqualTo(0);
violations = executableValidator.validateConstructorParameters
(constructor, new Object[] {null, ""});
assertThat(violations.size()).isEqualTo(1);
violations = executableValidator.validateConstructorParameters
(constructor, new Object[] {null, null});
assertThat(violations.size()).isEqualTo(2);
}
@Test
public void testConstructorParameters() throws NoSuchMethodException {
ExecutableValidator executableValidator = validator.forExecutables();
Constructor<RentalStation> constructor = RentalStation.class.getConstructor(String.class, String.class);
Set<ConstraintViolation<RentalStation>> violations = executableValidator.validateConstructorParameters
(constructor, new Object[] {"Hertz", ""});
assertThat(violations.size()).isEqualTo(0);
violations = executableValidator.validateConstructorParameters
(constructor, new Object[] {null, ""});
assertThat(violations.size()).isEqualTo(1);
violations = executableValidator.validateConstructorParameters
(constructor, new Object[] {null, null});
assertThat(violations.size()).isEqualTo(2);
}
@Override
public ExecutableValidator forExecutables() {
Assert.state(this.targetValidator != null, "No target Validator set");
return this.targetValidator.forExecutables();
}
@Override
public ExecutableValidator forExecutables() {
Assert.state(this.targetValidator != null, "No target Validator set");
return this.targetValidator.forExecutables();
}
private List<ConstraintViolation<?>> simulateValidation(Object controller, String methodName, Object... args) {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
ExecutableValidator executableValidator = validator.forExecutables();
List<ConstraintViolation<?>> result = new ArrayList<>();
// validate controller fields
result.addAll(validator.validate(controller));
// controller method parameters
Method method = getFirstMethod(controller.getClass(), methodName);
result.addAll(executableValidator.validateParameters(controller, method, args));
return result;
}
/**
* {@inheritDoc}
*/
public ExecutableValidator forExecutables()
{
return validator.forExecutables();
}
private List<ConstraintViolation<?>> simulateValidation(Object controller, String methodName, Object... args) {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
ExecutableValidator executableValidator = validator.forExecutables();
List<ConstraintViolation<?>> result = new ArrayList<>();
// validate controller fields
result.addAll(validator.validate(controller));
// controller method parameters
Method method = getFirstMethod(controller.getClass(), methodName);
result.addAll(executableValidator.validateParameters(controller, method, args));
return result;
}