使用名称创建bean时出错。结合bean验证和基于Spring的验证

时间:2017-03-04 18:46:09

标签: java spring validation spring-mvc

我想要结合bean验证和Spring验证(基于本书" Spring MVC初学者指南"),但是有错误: 我的日志:

structs

我的控制器:

2017-03-04 19:09:54 ERROR DispatcherServlet:502 - Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productController': Unsatisfied dependency expressed through field 'productValidator'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productValidator': Unsatisfied dependency expressed through field 'beanValidator'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.validation.Validator' available: expected single matching bean but found 2: org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean#0,validator
    at [...]

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'productValidator': Unsatisfied dependency expressed through field 'beanValidator'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.validation.Validator' available: expected single matching bean but found 2: org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean#0,validator
    at [...]

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'javax.validation.Validator' available: expected single matching bean but found 2: org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean#0,validator
    at [...]

我的班级验证

@Controller()
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private ProductService productService;

    @Autowired
    private ProductValidator productValidator;
[...]
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String processAddNewProductForm(@Valid @ModelAttribute("newProduct") Product productToBeAdded, BindingResult result,
                                           HttpServletRequest httpServletRequest){
        if(result.hasErrors())
            return "addProduct";

        String[] suppressedFields = result.getSuppressedFields();
        if(suppressedFields.length > 0){
            throw new RuntimeException("abc" + StringUtils.arrayToCommaDelimitedString(suppressedFields));
        }

        MultipartFile productImage = productToBeAdded.getProductImage();

        String rootDirectory = httpServletRequest.getSession().getServletContext().getRealPath("/");
        if(productImage != null && !productImage.isEmpty()){
            try {
                productImage.transferTo(new File(rootDirectory + "resources\\images\\" +
                                                    productToBeAdded.getProductId() + ".png"));
            } catch (IOException e) {
                throw new RuntimeException("abcd", e);
            }
        }

        productService.addProduct(productToBeAdded);
        return "redirect:/products";
    }

    @InitBinder
    public void initialiseBinder(WebDataBinder binder){
        binder.setValidator(productValidator);
    }
[...]
}

My DispatcherServlet-context

@Component
public class ProductValidator implements Validator {
    @Autowired
    private javax.validation.Validator beanValidator;

    private Set<Validator> springValidators;

    public ProductValidator() {
        this.springValidators = new HashSet<>();
    }

    public void setSpringValidators(Set<Validator> springValidators) {
        this.springValidators = springValidators;
    }

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

    @Override
    public void validate(Object target, Errors errors) {
        Set<ConstraintViolation<Object>> constraintViolations = beanValidator.validate(target);
        for(ConstraintViolation<Object> constraintViolation: constraintViolations){
            String propertyPath = constraintViolation.getPropertyPath().toString();
            String message = constraintViolation.getMessage();
            errors.rejectValue(propertyPath, "", message);
        }
        for(Validator validator: springValidators){
            validator.validate(target, errors);
        }
    }
}

最初,没有@Component注释,我添加了它,但没有任何改变

1 个答案:

答案 0 :(得分:1)

你得到的错误是b / c spring无法确定要注入到ProductValidator中的验证器bean,只需将其标记为bean配置文件中的主要部分,以便Spring知道要使用哪个。

 <bean id="validator" primary="true" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
        <property name="validationMessageSource" ref="messageSource"/>
 </bean>