java - Spring Boot - 表单上的自定义验证注释不起作用

标签 java validation spring-boot hibernate-annotations

我想要一个注释来验证 MultipartFile 是图像。我创建了一个 @interface 和一个 ConstraintValidator,并将注释添加到我的字段中。

其他验证注释,例如 @NotEmpty@Size(min = 0, max = 2) 工作正常。

这里是总结的代码。 This question有同样的问题,但答案对我不起作用。

表单.java:

@Validated
public class Form {

    @MultipartImage
    private MultipartFile image;

    ...
}

@Interface MultipartImage

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

import validation.MultipartFileImageConstraintValidator;

@Documented
@Constraint(validatedBy = { MultipartFileImageConstraintValidator.class })
@Target({ LOCAL_VARIABLE, FIELD, METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MultipartImage {

    String message() default "{MultipartImage.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

}

validator ,MultipartFileConstraintValidator.java

import java.io.IOException;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.springframework.web.multipart.MultipartFile;

public class MultipartFileConstraintValidator implements ConstraintValidator<MultipartImage, MultipartFile> {


@Override
public void initialize(final MultipartImage constraintAnnotation) {
}

@Override
public boolean isValid(final MultipartFile file, final ConstraintValidatorContext context) {
    return false;
}

这是 Controller 中的表单提交方法

@RequestMapping(value = "/formsubmit", method = RequestMethod.POST)
public ModelAndView handleForm(@Validated final Form form,
        final BindingResult bindingResult) {

    if (bindingResult.hasErrors()) {
        ...
        // returns the model
    }
}

在@Configuration文件中设置 validator ,请参阅https://stackoverflow.com/a/21965098/4161471

@Configuration
@ConfigurationProperties("static")
@AutoConfigureAfter(DispatcherServletAutoConfiguration.class)
public class StaticResourceConfig extends WebMvcConfigurerAdapter {

...

@Bean(name = "validator")
public LocalValidatorFactoryBean validator() {
    LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
    bean.setValidationMessageSource(messageSource());
    return bean;
}

@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
    final MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
    methodValidationPostProcessor.setValidator(validator());

    return methodValidationPostProcessor;
}

@Override
public Validator getValidator() {
    return validator();
}

@Bean
public ReloadableResourceBundleMessageSource messageSource() {
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    // Load files containing message keys.
    // Order matters. The first files override later files.
    messageSource.setBasenames(//
            // load messages and ValidationMessages from a folder relative to the jar
            "file:locale/messages", //
            "file:locale/ValidationMessages", //
            // load from within the jar
            "classpath:locale/messages", //
            "classpath:locale/ValidationMessages" //
    );
    messageSource.getBasenameSet();
    messageSource.setCacheSeconds(10); // reload messages every 10 seconds
    return messageSource;
}

}

最佳答案

我的原始代码中缺少信息,特别是有关 Controller 的信息,其中定义并绑定(bind)了附加 validator 。它使用错误的方法来包含 validator FormValidator,并覆盖注释验证。

binder.setValidator(formValidator) 覆盖任何其他 validator 。相反,应该使用 binder.addValidators(formValidator)!

@Controller
public class FormController {

     @Autowired
     final private FormValidator formValidator;

     @InitBinder("form")
     protected void initBinder(WebDataBinder binder) {
        // correct
        binder.addValidators(formValidator);
        // wrong
        //binder.setValidator(formValidator);
    }

    ...

    @RequestMapping(value = "/formsubmit", method = RequestMethod.POST)
    public ModelAndView handleForm(@Validated final Form form, final BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            ...
            // returns the model
        }
    ...
    }
}

我还删除了 @Configuration 类中的 Bean MethodValidationPostProcessor

关于java - Spring Boot - 表单上的自定义验证注释不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41020674/

相关文章:

javascript - 通过 BSB 查询澳大利亚银行,使用 Javascript

spring - Autowire 不适用于 Controller Spring Boot

java - 黑莓按下 buttonfield n 秒

java - 嵌套异常是 org.hibernate.exception.JDBCConnectionException : Unable to acquire JDBC Connection

javascript - 关闭 Bootstrap 模式后重置验证消息

java - 无法从生产环境中的数据源确定 jdbc url

java - 如果我有一个复杂的响应对象,如何使用 JsonIninclude 注释忽略空值

java - 什么是 com.android.support :appcompat-v7?

java - 使用 Tomcat 7 配置 Servlet、JSP

ajax - 如何在 Magento 结账时不显眼地添加新的验证方法