Я использую следующий класс, чтобы вручную выполнить проверку bean-компонента JSR-303 и HibernateValidator с помощью валидатора Spring.Возможно, это может быть полезно.
BeanValidator.java
import java.util.Locale;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
public class BeanValidator implements org.springframework.validation.Validator, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(BeanValidator.class.getName());
private Validator validator;
@Autowired
MessageSource messageSource;
@Override
public void afterPropertiesSet() throws Exception {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
validator = validatorFactory.usingContext().getValidator();
}
@Override
public boolean supports(Class clazz) {
return true;
}
@Override
public void validate(Object target, Errors errors) {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(target);
for (ConstraintViolation<Object> constraintViolation : constraintViolations) {
String propertyPath = constraintViolation.getPropertyPath().toString();
String message;
try {
message = messageSource.getMessage(constraintViolation.getMessage(), new Object[]{}, Locale.getDefault());
} catch (NoSuchMessageException e) {
log.error(String.format("Could not interpolate message \"%s\" for validator. "
+ e.getMessage(), constraintViolation.getMessage()), e);
message = constraintViolation.getMessage();
}
errors.rejectValue(propertyPath, "", message);
}
}
}
SpringMessageSourceMessageInterpolator.java
import javax.validation.MessageInterpolator;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.MessageSourceAware;
import org.springframework.context.NoSuchMessageException;
public class SpringMessageSourceMessageInterpolator extends ResourceBundleMessageInterpolator implements MessageInterpolator, MessageSourceAware, InitializingBean {
@Autowired
private MessageSource messageSource;
@Override
public String interpolate(String messageTemplate, Context context) {
try {
return messageSource.getMessage(messageTemplate, new Object[]{}, Locale.getDefault());
} catch (NoSuchMessageException e) {
return super.interpolate(messageTemplate, context);
}
}
@Override
public String interpolate(String messageTemplate, Context context, Locale locale) {
try {
return messageSource.getMessage(messageTemplate, new Object[]{}, locale);
} catch (NoSuchMessageException e) {
return super.interpolate(messageTemplate, context, locale);
}
}
@Override
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
@Override
public void afterPropertiesSet() throws Exception {
if (messageSource == null) {
throw new IllegalStateException("MessageSource was not injected, could not initialize "
+ this.getClass().getSimpleName());
}
}
}
applicationContext.xml
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource" p:basename="messages"/>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="messageInterpolator">
<bean class="com.company.utils.spring.SpringMessageSourceMessageInterpolator" />
</property>
</bean>
Пример свойства компонента
@NotNull(message = "validation.mandatoryField")
private ClientGroup clientGroup;
Пример проверки
@Controller
public class MyController {
@Autowired
private BeanValidator validator;
@RequestMapping("/foo", method=RequestMethod.POST)
public void processFoo(ModelAttribute("foo") Foo foo, BindingResult result, Model model) {
//...
validator.validate(foo, result);
}
}