How to create custom validators in spring?
Creating custom validators in Spring can be accomplished using the Validator
interface or by using annotations with the ConstraintValidator
interface. Below are the steps for both approaches.
Validator
InterfaceValidator
interface.import org.springframework.validation.Validator;
import org.springframework.validation.Errors;
public class CustomValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return YourModelClass.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
YourModelClass yourModel = (YourModelClass) target;
// Custom validation logic
if (yourModel.getSomeField() == null) {
errors.rejectValue("someField", "field.required", "Field is required");
}
// Add more validation rules as needed
}
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
@Configuration
public class AppConfig {
@Bean
public Validator validator() {
return new CustomValidator();
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class YourController {
@Autowired
private Validator validator;
@PostMapping("/submit")
public String submitForm(YourModelClass yourModel, BindingResult bindingResult) {
validator.validate(yourModel, bindingResult);
if (bindingResult.hasErrors()) {
return "formView"; // return to the form view with errors
}
// Process the valid data
return "successView";
}
}
ConstraintValidator
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Constraint(validatedBy = CustomValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidCustom {
String message() default "Invalid value";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
ConstraintValidator
: Create a class that implements ConstraintValidator
.import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class CustomValidator implements ConstraintValidator<ValidCustom, String> {
@Override
public void initialize(ValidCustom constraintAnnotation) {
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// Custom validation logic
return value != null && !value.isEmpty(); // Example: check if not null or empty
}
}
public class YourModelClass {
@ValidCustom(message = "Custom validation failed")
private String someField;
// Getters and Setters
}
@Valid
to trigger validation.import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class YourController {
@PostMapping("/submit")
public String submitForm(@Valid YourModelClass yourModel, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "formView"; // return to the form view with errors
}
// Process the valid data
return "successView";
}
}
Validator
Interface: This approach is more manual and gives you full control over the validation process.ConstraintValidator
: This approach is more declarative and integrates well with the Java Bean Validation API (JSR 380).Choose the approach that best fits your needs based on the complexity of your validation logic and your application's architecture.