I've been using Hibernate Validator in my Spring project. I'm about to validate my JUser
Object automatically. i.e, I want Spring to validate the Object and set errors in BindigResult. But It doesn't work.
<properties>
<spring.version>4.3.5.RELEASE</spring.version>
<spring.security.version>4.0.2.RELEASE</spring.security.version>
<hibernate.version>4.3.11.Final</hibernate.version>
<validation-api.version>1.1.0.Final</validation-api.version>
<hibernate-validator.version>5.4.0.Final</hibernate-validator.version>
</properties>
....
...
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<context:annotation-config />
<context:component-scan base-package="my.project.controller" />
<mvc:annotation-driven validator="validator">
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"/>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
</bean>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<property name="validator" ref="validator"/>
</bean>
<bean id="localeResolver"
class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="en" />
</bean>
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.NotEmpty;
@Entity
public class JUser implements Officeable {
@Id
private Long id;
@Column(unique = true, nullable = false)
private String username;
private String password;
@NotEmpty
private String firstName;
@NotEmpty
private String lastName;
private String tel;
}
import javax.validation.ConstraintViolationException;
....
@RequestMapping(value = "/update", method = RequestMethod.POST)
public String update2(HttpServletRequest request, Model model, @ModelAttribute("user") @Valid JUser user, BindingResult result) {
if (!result.hasErrors()) {
System.out.println("binding result has no errors for user ");
try {
JUser updated = userService.update(user);
model.addAttribute("user", updated);
} catch (MessageException | DataIntegrityViolationException ex) {
result.reject("user", ex.getMessage());
} catch (ConstraintViolationException cvex) {
for (ConstraintViolation cv : cvex.getConstraintViolations()) {
result.rejectValue(cv.getPropertyPath().toString(),cv.getMessageTemplate() , cv.getMessage());
}
}
}
return "user/manage";
}
As you see in the above controller method I want Spring to validate the user
Object and set errors in BindigResult
. But It does not work.
For example when user
has empty firstName
I face the output:
output:
binding result has no errors for user
and I have to catch hibernate thrown exceptions by hand:
ConstraintViolationException: may not be empty ...
more description. I've used String @Validated
annotation and It did not work as well. I've read more than ten related stackoverflow questions and they didn't solved my problem.
First thing, can you test if validate is working after adding below code?
pom.xml
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>
@Bean // in configuration
public Validator validator() {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
return validatorFactory.getValidator();
}
@Autowired //in controller
private Validator validator;
public <T> void validate(T t) {
Set validate = this.validator.validate(t);
if(!validate.isEmpty()) {
throw new RuntimeException();
}
}
If this works, then can suggest you further to simplify it.
As per spring-mvc-4.3.xsd
The bean name of the Validator that is to be used to validate Controller model objects. This attribute is not required, and only needs to be specified if a custom Validator needs to be configured. If not specified, JSR-303 validation will be installed if a JSR-303 provider is present on the classpath.
I don't see you wrote any custom validator so you can change
<mvc:annotation-driven validator="validator">
to support the default JSR-303
<mvc:annotation-driven />
Example: Spring 3 MVC and JSR303 @Valid example
Update 1
Could you also try removing validation-api.version
This transitively pulls in the dependency to the Bean Validation API (javax.validation:validation-api:1.1.0.Final).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With