1

I am trying to incorporate annotated validation rules along with some custom validation. I have a details entity which looks like the following:

public class DetailsEntity {    
    @NotEmpty(message = "Name is required")
    private String name;
    private String customField;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCustomField() {
        return customField;
    }

    public void setCustomField(String customField) {
        this.customField = customField;
    }
}

I then have a controller that looks like this:

@Controller
public class EntityController {

    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public @ResponseBody DetailsEntity create(@RequestBody @Valid
        DetailsEntity details) {
        //Do some creation work
    }
}

This all works great out of the box. The problem is when I try to use a custom validator along with my entity. My validator looks like this:

@Component
public class EntityValidator implements Validator {

    @Override
    public boolean supports(Class<?> aClass) {
        return aClass.isAssignableFrom(DetailsEntity.class);
    }

    @Override
    public void validate(Object o, Errors errors) {
        DetailsEntity entity = (DetailsEntity) o;
        if (entity.getCustomField().equals("Some bad value")) {
            errors.reject("Bad custom value supplied");
        }
    }
}

I've tried injecting my validator two ways. One is using the @InitBinder in the controller, and the other is setting a global validator in the spring configuration (<mvc:annotation-driven validator="entityValidator" />). Either way I do it, the custom validator works fine, but my @NotEmpty annotation gets ignored. How can I use both the annotations as well as a custom validator?

2 Answers 2

2

Use SpringValidatorAdapter as base class of your custom validator and override validate() method:

public void validate(Object target, Errors errors) {
                // check JSR-303 Constraints
        super.validate(target, errors);
                // Add you custom validation here.

    }

Or inject a LocalValidationFactoryBean in you custom validator and call to validate(target, errors) before or after your custom validation.

Sign up to request clarification or add additional context in comments.

2 Comments

That send me down the right path, ended up looking at this page: nonrepeatable.blogspot.com/2010/04/…
I would add that if one want to use group validations, the groups must be added in the the validate method. Otherwise those validations are not executed!
1

@NotEmpty is a JSR-303 annotation, and we need to use an implementation of it like HiberanteValidator, we need to add Hibernate-Validator jar to your lib directory. Using this jar we can use @NotEmpty, @NotNull...all JSR 303 annotations.

1 Comment

I came here because I expected Spring to reject my invalid request but it didn't. Fixed by simply adding org.hibernate.validator:hibernate-validator dependency. This answer is superior to the accepted answer because it utilizes spring built-in functionality instead of doing the hard work yourself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.