Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can JSR 303 Bean Validation be used with Spring Data Rest?

I understand from the docs http://docs.spring.io/spring-data/rest/docs/2.1.2.RELEASE/reference/html/validation-chapter.html that I can declare validators with certain prefixes.

I'm using JSR 303 so my domain entities are annotated with validation annotations.

Can - and if yes, how - I use JSR 303 Bean Validation with Spring Data Rest?

PS: I'm using Spring Boot

like image 490
Marcel Overdijk Avatar asked Aug 09 '14 16:08

Marcel Overdijk


People also ask

In which implementation is the JSR 303 standard used?

Spring Framework became JSR303 compliant from version 3 onward I think. Spring Framework 4.0 supports Bean Validation 1.0 (JSR-303) and Bean Validation 1.1 (JSR-349) in terms of setup support, also adapting it to Spring's Validator interface.

What is JSR 303 Bean Validation?

Bean Validation. JSR-303 bean validation is an specification whose objective is to standardize the validation of Java beans through annotations. The objective of the JSR-303 standard is to use annotations directly in a Java bean class.


3 Answers

This seems to work:

@Configuration
protected static class CustomRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {

    @Autowired
    private Validator validator;

    @Override
    protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
        validatingListener.addValidator("beforeCreate", validator);
        validatingListener.addValidator("beforeSave", validator);
    }
}
like image 168
Marcel Overdijk Avatar answered Oct 16 '22 23:10

Marcel Overdijk


To customize the spring data-rest configuration, register a RepositoryRestConfigurer (or extend RepositoryRestConfigurerAdapter) and implement or override the configureValidatingRepositoryEventListener method for your specific use case.

public class CustomRepositoryRestConfigurer extends RepositoryRestConfigurerAdapter {

    @Autowired
    private Validator validator;

    @Override
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
        validatingListener.addValidator("beforeCreate", validator);
        validatingListener.addValidator("beforeSave", validator);
    }
}
like image 7
herau Avatar answered Oct 17 '22 01:10

herau


//Edit - Giving more information based on the comment for this answer and changing the code accordingly.

Related Documentation - http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

Notes

//This is making the handler global for the application
//If this were on a @Controller bean it would be local to the controller
@ControllerAdvice

//Specifies to return a 400
@ResponseStatus(value = HttpStatus.BAD_REQUEST)

//Which exception to handle
@ExceptionHandler(ConstraintViolationException.class)

//Specifies to make the return value JSON.
@ResponseBody

//This class if for modeling the error we return.
//(Could use HashMap<String, Object> also if you feel it's cleaner)
class ConstraintViolationModel {

This is an exception handler for Spring that should work in spring boot just fine.

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice
public class ExceptionHandlingController {
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ExceptionHandler(ConstraintViolationException.class)
    public @ResponseBody List<ConstraintViolationModel> handleConstraintViolation(
            HttpServletRequest req, final ConstraintViolationException exception) {
        ArrayList<ConstraintViolationModel> list = new ArrayList<ConstraintViolationModel>();
        for (ConstraintViolation<?> violation : exception
                .getConstraintViolations()) {
            list.add(new ConstraintViolationModel(violation.getPropertyPath()
                    .toString(), violation.getMessage(), violation
                    .getInvalidValue()));
        }
        return list;
    }

    private static class ConstraintViolationModel {
        public String field;
        public String message;
        public Object invalidValue;

        public ConstraintViolationModel(String field, String message,
                Object invalidValue) {
            this.field = field;
            this.message = message;
            this.invalidValue = invalidValue;
        }
    }
}
like image 1
Zergleb Avatar answered Oct 17 '22 01:10

Zergleb