JSR 303 Bean验证可以与Spring Data Rest一起使用吗?

问题描述 投票:12回答:4

我从文档http://docs.spring.io/spring-data/rest/docs/2.1.2.RELEASE/reference/html/validation-chapter.html了解到我可以声明具有某些前缀的验证器。

我正在使用JSR 303,因此我的域实体使用验证注释进行注释。

可以 - 如果是,如何 - 我在Spring Data Rest中使用JSR 303 Bean验证?

PS:我正在使用Spring Boot

java spring-boot spring-data-jpa spring-data-rest
4个回答
14
投票

这似乎有效:

@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);
    }
}

5
投票

要自定义spring数据休息配置,请注册RepositoryRestConfigurer(或扩展RepositoryRestConfigurerAdapter)并为您的特定用例实现或覆盖configureValidatingRepositoryEventListener方法。

public class CustomRepositoryRestConfigurer extends RepositoryRestConfigurerAdapter {

    @Autowired
    private Validator validator;

    @Override
    public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
        validatingListener.addValidator("beforeCreate", validator);
        validatingListener.addValidator("beforeSave", validator);
    }
}

1
投票

//编辑 - 根据此答案的注释提供更多信息并相应地更改代码。

相关文档 - http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

笔记

//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 {

这是一个Spring的异常处理程序,应该可以在spring boot中正常工作。

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;
        }
    }
}

0
投票

这个(validatingListener.addValidator("beforeCreate", validator);)并没有真正完全起作用,因为验证只管理实体。

因此,如果您尝试对非实体进行验证,则会出现一个令人讨厌的错误,说org.springframework.beans.NotReadablePropertyException: Invalid property '...' of bean class [... the non-entity one ...]: Bean property '....' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

虽然显然更费力,但您可以直接在Validator上手动执行验证,例如:

@Component("beforeSaveListingValidator")
public class BeforeSaveListingValidator implements Validator {

    @Autowired
    private LocalValidatorFactoryBean validator;

    @Override
    public void validate(Object object, Errors errors) {
        BindingResult bindingResult = new BeanPropertyBindingResult(object, errors.getObjectName());
        validator.validate(object, bindingResult);
        errors.addAllErrors(bindingResult);
© www.soinside.com 2019 - 2024. All rights reserved.