Initial support for Bean Validation 1.1 and Hibernate Validator 5.0
MethodValidationInterceptor autodetects Bean Validation 1.1's ExecutableValidator API now and uses it in favor of Hibernate Validator 4.2's native variant. SpringConstraintValidatorFactory implements Bean Validation 1.1 "releaseInstance" method against new "destroyBean(Object)" method in AutowireCapableBeanFactory. LocalValidatorFactoryBean adapts Spring-provided ParameterNameDiscoverer onto Bean Validation 1.1's ParameterNameProvider mechanism. LocalValidatorFactoryBean reflectively adapts between the different ResourceBundleLocator SPI location in Hibernate Validator 4.2 versus 5.0. LocalValidatorFactoryBean implements Bean Validation 1.1 "close" method. Note: We still compile against Bean Validation 1.0 in order to not have to implement "forExecutables()" and "getParameterNameDiscoverer()" in LocalValidatorFactoryBean, SpringValidatorAdapter and CustomValidatorBean. Implementing those methods would imply references to Bean Validation 1.1 interfaces that break runtime compatibility with Bean Validation 1.0. Unfortunately, this means that all Bean Validation 1.1 API access has to be done via reflection. Issue: SPR-8199
This commit is contained in:
parent
23bf5f563b
commit
0d0122239d
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -17,7 +17,14 @@
|
|||
package org.springframework.validation.beanvalidation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import javax.validation.Configuration;
|
||||
|
|
@ -31,12 +38,18 @@ import javax.validation.ValidatorFactory;
|
|||
|
||||
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.support.MessageSourceResourceBundle;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* This is the central class for {@code javax.validation} (JSR-303) setup
|
||||
|
|
@ -51,6 +64,15 @@ import org.springframework.util.CollectionUtils;
|
|||
* you will almost always use the default Validator anyway. This can also be injected directly
|
||||
* into any target dependency of type {@link org.springframework.validation.Validator}!
|
||||
*
|
||||
* <p>As of Spring 4.0, this class supports Bean Validation 1.0 and 1.1, with special support
|
||||
* for Hibernate Validator 4.x and 5.0 (see {@link #setValidationMessageSource}).
|
||||
*
|
||||
* <p>Note that Bean Validation 1.1's {@code #forExecutables} method isn't supported: We do not
|
||||
* expect that method to be called by application code; consider {@link MethodValidationInterceptor}
|
||||
* instead. If you really need programmatic {@code #forExecutables} access, inject this class as
|
||||
* a {@link ValidatorFactory} and call {@link #getValidator()} on it, then {@code #forExecutables}
|
||||
* on the returned native {@link Validator} reference instead of directly on this class.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see javax.validation.ValidatorFactory
|
||||
|
|
@ -59,7 +81,10 @@ import org.springframework.util.CollectionUtils;
|
|||
* @see javax.validation.ValidatorFactory#getValidator()
|
||||
*/
|
||||
public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
||||
implements ValidatorFactory, ApplicationContextAware, InitializingBean {
|
||||
implements ValidatorFactory, ApplicationContextAware, InitializingBean, DisposableBean {
|
||||
|
||||
private static final Method closeMethod = ClassUtils.getMethodIfAvailable(ValidatorFactory.class, "close");
|
||||
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private Class providerClass;
|
||||
|
|
@ -70,6 +95,8 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
|||
|
||||
private ConstraintValidatorFactory constraintValidatorFactory;
|
||||
|
||||
private ParameterNameDiscoverer parameterNameDiscoverer;
|
||||
|
||||
private Resource[] mappingLocations;
|
||||
|
||||
private final Map<String, String> validationPropertyMap = new HashMap<String, String>();
|
||||
|
|
@ -109,9 +136,8 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
|||
* <p>Specify either this property or {@link #setMessageInterpolator "messageInterpolator"},
|
||||
* not both. If you would like to build a custom MessageInterpolator, consider deriving from
|
||||
* Hibernate Validator's {@link ResourceBundleMessageInterpolator} and passing in a
|
||||
* Spring {@link MessageSourceResourceBundleLocator} when constructing your interpolator.
|
||||
* Spring-based {@code ResourceBundleLocator} when constructing your interpolator.
|
||||
* @see ResourceBundleMessageInterpolator
|
||||
* @see MessageSourceResourceBundleLocator
|
||||
*/
|
||||
public void setValidationMessageSource(MessageSource messageSource) {
|
||||
this.messageInterpolator = HibernateValidatorDelegate.buildMessageInterpolator(messageSource);
|
||||
|
|
@ -134,6 +160,15 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
|||
this.constraintValidatorFactory = constraintValidatorFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ParameterNameDiscoverer to use for resolving method and constructor
|
||||
* parameter names if needed for message interpolation.
|
||||
* <p>Default is a {@link org.springframework.core.LocalVariableTableParameterNameDiscoverer}.
|
||||
*/
|
||||
public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
|
||||
this.parameterNameDiscoverer = parameterNameDiscoverer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify resource locations to load XML constraint mapping files from, if any.
|
||||
*/
|
||||
|
|
@ -202,6 +237,8 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
|||
configuration.constraintValidatorFactory(targetConstraintValidatorFactory);
|
||||
}
|
||||
|
||||
configureParameterNameProviderIfPossible(configuration);
|
||||
|
||||
if (this.mappingLocations != null) {
|
||||
for (Resource location : this.mappingLocations) {
|
||||
try {
|
||||
|
|
@ -221,6 +258,58 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
|||
setTargetValidator(this.validatorFactory.getValidator());
|
||||
}
|
||||
|
||||
private void configureParameterNameProviderIfPossible(Configuration configuration) {
|
||||
try {
|
||||
Class<?> parameterNameProviderClass =
|
||||
ClassUtils.forName("javax.validation.ParameterNameProvider", getClass().getClassLoader());
|
||||
Method parameterNameProviderMethod =
|
||||
Configuration.class.getMethod("parameterNameProvider", parameterNameProviderClass);
|
||||
final Object defaultProvider = ReflectionUtils.invokeMethod(
|
||||
Configuration.class.getMethod("getDefaultParameterNameProvider"), configuration);
|
||||
final ParameterNameDiscoverer discoverer = (this.parameterNameDiscoverer != null ?
|
||||
this.parameterNameDiscoverer : new LocalVariableTableParameterNameDiscoverer());
|
||||
Object parameterNameProvider = Proxy.newProxyInstance(getClass().getClassLoader(),
|
||||
new Class[] {parameterNameProviderClass}, new InvocationHandler() {
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if (method.getName().equals("getParameterNames")) {
|
||||
String[] result = null;
|
||||
if (args[0] instanceof Constructor) {
|
||||
result = discoverer.getParameterNames((Constructor) args[0]);
|
||||
}
|
||||
else if (args[0] instanceof Method) {
|
||||
result = discoverer.getParameterNames((Method) args[0]);
|
||||
}
|
||||
if (result != null) {
|
||||
return Arrays.asList(result);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
return method.invoke(defaultProvider, args);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// toString, equals, hashCode
|
||||
try {
|
||||
return method.invoke(this, args);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ReflectionUtils.invokeMethod(parameterNameProviderMethod, configuration, parameterNameProvider);
|
||||
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Bean Validation 1.1 API not available - simply not applying the ParameterNameDiscoverer
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Validator getValidator() {
|
||||
return this.validatorFactory.getValidator();
|
||||
|
|
@ -242,14 +331,61 @@ public class LocalValidatorFactoryBean extends SpringValidatorAdapter
|
|||
return this.validatorFactory.getConstraintValidatorFactory();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
ReflectionUtils.invokeMethod(closeMethod, this.validatorFactory);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard-coded Hibernate Validator 4.1 dependency.
|
||||
* Inner class to avoid a hard-coded Hibernate Validator dependency.
|
||||
*/
|
||||
private static class HibernateValidatorDelegate {
|
||||
|
||||
public static MessageInterpolator buildMessageInterpolator(MessageSource messageSource) {
|
||||
return new ResourceBundleMessageInterpolator(new MessageSourceResourceBundleLocator(messageSource));
|
||||
public static MessageInterpolator buildMessageInterpolator(final MessageSource messageSource) {
|
||||
Class<?> locatorClass;
|
||||
try {
|
||||
// Hibernate Validator 5.x
|
||||
locatorClass = ClassUtils.forName(
|
||||
"org.hibernate.validator.spi.resourceloading.ResourceBundleLocator",
|
||||
HibernateValidatorDelegate.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
try {
|
||||
// Hibernate Validator 4.x
|
||||
locatorClass = ClassUtils.forName(
|
||||
"org.hibernate.validator.resourceloading.ResourceBundleLocator",
|
||||
HibernateValidatorDelegate.class.getClassLoader());
|
||||
}
|
||||
catch (ClassNotFoundException ex2) {
|
||||
throw new IllegalStateException("Neither Hibernate Validator 5.x nor 4.x API found");
|
||||
}
|
||||
}
|
||||
Object locator = Proxy.newProxyInstance(HibernateValidatorDelegate.class.getClassLoader(),
|
||||
new Class[] {locatorClass}, new InvocationHandler() {
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
if (method.getName().equals("getResourceBundle")) {
|
||||
return new MessageSourceResourceBundle(messageSource, (Locale) args[0]);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
return method.invoke(this, args);
|
||||
}
|
||||
catch (InvocationTargetException ex) {
|
||||
throw ex.getTargetException();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
try {
|
||||
return ResourceBundleMessageInterpolator.class.getConstructor(locatorClass).newInstance(locator);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Unexpected Hibernate Validator API mismatch", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.validation.beanvalidation;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.hibernate.validator.resourceloading.ResourceBundleLocator;
|
||||
|
||||
import org.springframework.context.MessageSource;
|
||||
import org.springframework.context.support.MessageSourceResourceBundle;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Implementation of Hibernate Validator 4.1's {@link ResourceBundleLocator} interface,
|
||||
* exposing a Spring {@link MessageSource} as localized {@link MessageSourceResourceBundle}.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.4
|
||||
* @see ResourceBundleLocator
|
||||
* @see MessageSource
|
||||
* @see MessageSourceResourceBundle
|
||||
*/
|
||||
public class MessageSourceResourceBundleLocator implements ResourceBundleLocator {
|
||||
|
||||
private final MessageSource messageSource;
|
||||
|
||||
/**
|
||||
* Build a MessageSourceResourceBundleLocator for the given MessageSource.
|
||||
* @param messageSource the Spring MessageSource to wrap
|
||||
*/
|
||||
public MessageSourceResourceBundleLocator(MessageSource messageSource) {
|
||||
Assert.notNull(messageSource, "MessageSource must not be null");
|
||||
this.messageSource = messageSource;
|
||||
}
|
||||
|
||||
public ResourceBundle getResourceBundle(Locale locale) {
|
||||
return new MessageSourceResourceBundle(this.messageSource, locale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,7 +16,10 @@
|
|||
|
||||
package org.springframework.validation.beanvalidation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
|
|
@ -29,6 +32,7 @@ import org.hibernate.validator.method.MethodConstraintViolationException;
|
|||
import org.hibernate.validator.method.MethodValidator;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
|
|
@ -45,25 +49,48 @@ import org.springframework.validation.annotation.Validated;
|
|||
* at the type level of the containing target class, applying to all public service methods
|
||||
* of that class. By default, JSR-303 will validate against its default group only.
|
||||
*
|
||||
* <p>As of Spring 3.1, this functionality requires Hibernate Validator 4.2 or higher.
|
||||
* Once Bean Validation 1.1 becomes available, this class will autodetect a compliant
|
||||
* provider and automatically use the standard method validation support there.
|
||||
* <p>As of Spring 4.0, this functionality requires either a Bean Validation 1.1 provider
|
||||
* or Bean Validation 1.0 with Hibernate Validator 4.2 or higher. The actual provider
|
||||
* will be autodetected and automatically adapted.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
* @see MethodValidationPostProcessor
|
||||
* @see javax.validation.executable.ExecutableValidator
|
||||
* @see org.hibernate.validator.method.MethodValidator
|
||||
*/
|
||||
public class MethodValidationInterceptor implements MethodInterceptor {
|
||||
|
||||
private final MethodValidator validator;
|
||||
private static Method forExecutablesMethod;
|
||||
|
||||
private static Method validateParametersMethod;
|
||||
|
||||
private static Method validateReturnValueMethod;
|
||||
|
||||
static {
|
||||
try {
|
||||
forExecutablesMethod = Validator.class.getMethod("forExecutables");
|
||||
Class<?> executableValidatorClass = forExecutablesMethod.getReturnType();
|
||||
validateParametersMethod = executableValidatorClass.getMethod(
|
||||
"validateParameters", Object.class, Method.class, Object[].class, Class[].class);
|
||||
validateReturnValueMethod = executableValidatorClass.getMethod(
|
||||
"validateReturnValue", Object.class, Method.class, Object.class, Class[].class);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Bean Validation 1.1 ExecutableValidator API not available
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final Validator validator;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new MethodValidationInterceptor using a default JSR-303 validator underneath.
|
||||
*/
|
||||
public MethodValidationInterceptor() {
|
||||
this(Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory());
|
||||
this(forExecutablesMethod != null ? Validation.buildDefaultValidatorFactory() :
|
||||
HibernateValidatorDelegate.buildValidatorFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -79,24 +106,33 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
|||
* @param validator the JSR-303 Validator to use
|
||||
*/
|
||||
public MethodValidationInterceptor(Validator validator) {
|
||||
this.validator = validator.unwrap(MethodValidator.class);
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
Class[] groups = determineValidationGroups(invocation);
|
||||
Set<MethodConstraintViolation<Object>> result = this.validator.validateAllParameters(
|
||||
invocation.getThis(), invocation.getMethod(), invocation.getArguments(), groups);
|
||||
if (!result.isEmpty()) {
|
||||
throw new MethodConstraintViolationException(result);
|
||||
if (forExecutablesMethod != null) {
|
||||
Object executableValidator = ReflectionUtils.invokeMethod(forExecutablesMethod, this.validator);
|
||||
Set<ConstraintViolation<?>> result = (Set<ConstraintViolation<?>>)
|
||||
ReflectionUtils.invokeMethod(validateParametersMethod, executableValidator,
|
||||
invocation.getThis(), invocation.getMethod(), invocation.getArguments(), groups);
|
||||
if (!result.isEmpty()) {
|
||||
throw new ConstraintViolationException(result);
|
||||
}
|
||||
Object returnValue = invocation.proceed();
|
||||
result = (Set<ConstraintViolation<?>>)
|
||||
ReflectionUtils.invokeMethod(validateReturnValueMethod, executableValidator,
|
||||
invocation.getThis(), invocation.getMethod(), returnValue, groups);
|
||||
if (!result.isEmpty()) {
|
||||
throw new ConstraintViolationException(result);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
Object returnValue = invocation.proceed();
|
||||
result = this.validator.validateReturnValue(
|
||||
invocation.getThis(), invocation.getMethod(), returnValue, groups);
|
||||
if (!result.isEmpty()) {
|
||||
throw new MethodConstraintViolationException(result);
|
||||
else {
|
||||
return HibernateValidatorDelegate.invokeWithinValidation(invocation, this.validator, groups);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -111,4 +147,33 @@ public class MethodValidationInterceptor implements MethodInterceptor {
|
|||
return (valid != null ? valid.value() : new Class[0]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inner class to avoid a hard-coded Hibernate Validator dependency.
|
||||
*/
|
||||
private static class HibernateValidatorDelegate {
|
||||
|
||||
public static ValidatorFactory buildValidatorFactory() {
|
||||
return Validation.byProvider(HibernateValidator.class).configure().buildValidatorFactory();
|
||||
}
|
||||
|
||||
public static Object invokeWithinValidation(MethodInvocation invocation, Validator validator, Class[] groups)
|
||||
throws Throwable {
|
||||
|
||||
MethodValidator methodValidator = validator.unwrap(MethodValidator.class);
|
||||
Set<MethodConstraintViolation<Object>> result = methodValidator.validateAllParameters(
|
||||
invocation.getThis(), invocation.getMethod(), invocation.getArguments(), groups);
|
||||
if (!result.isEmpty()) {
|
||||
throw new MethodConstraintViolationException(result);
|
||||
}
|
||||
Object returnValue = invocation.proceed();
|
||||
result = methodValidator.validateReturnValue(
|
||||
invocation.getThis(), invocation.getMethod(), returnValue, groups);
|
||||
if (!result.isEmpty()) {
|
||||
throw new MethodConstraintViolationException(result);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -50,4 +50,8 @@ public class SpringConstraintValidatorFactory implements ConstraintValidatorFact
|
|||
return this.beanFactory.createBean(key);
|
||||
}
|
||||
|
||||
public void releaseInstance(ConstraintValidator<?, ?> instance) {
|
||||
this.beanFactory.destroyBean(instance);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -22,7 +22,6 @@ import javax.validation.constraints.Max;
|
|||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.groups.Default;
|
||||
|
||||
import org.hibernate.validator.method.MethodConstraintViolationException;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
|
|
@ -61,21 +60,21 @@ public class MethodValidationTests {
|
|||
assertNotNull(proxy.myValidMethod("value", 15));
|
||||
fail("Should have thrown MethodConstraintViolationException");
|
||||
}
|
||||
catch (MethodConstraintViolationException ex) {
|
||||
catch (javax.validation.ValidationException ex) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
assertNotNull(proxy.myValidMethod(null, 5));
|
||||
fail("Should have thrown MethodConstraintViolationException");
|
||||
}
|
||||
catch (MethodConstraintViolationException ex) {
|
||||
catch (javax.validation.ValidationException ex) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
assertNotNull(proxy.myValidMethod("value", 0));
|
||||
fail("Should have thrown MethodConstraintViolationException");
|
||||
}
|
||||
catch (MethodConstraintViolationException ex) {
|
||||
catch (javax.validation.ValidationException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue