2016-12-07 3 views
1

Ich möchte eine Anmerkung, die überprüft, dass ein MultipartFile ein Bild ist. Ich habe eine @interface und eine ConstraintValidator erstellt und die Anmerkung zu meinem Feld hinzugefügt.Spring Boot - Benutzerdefinierte Validierung Annotation auf Formular funktioniert nicht

Andere Validierungsanmerkungen wie @NotEmpty und @Size(min = 0, max = 2) funktionieren einwandfrei.

Hier ist der Code in der Zusammenfassung. This question hat das gleiche Problem, aber die Antwort funktioniert nicht für mich.

Form.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 {}; 

} 

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

Hier ist die Form Methode in der

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

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

Validator in der @Configuration Datei einrichten, finden 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; 
} 

}

+0

Hoppla, ich drücke zu früh einreichen. Ich werde bald weitere Informationen hinzufügen. – aSemy

+0

MultipartFileConstraintValidator sollte ConstraintValidator implementieren. Sind andere Einschränkungen wie '@ Size' in der' Form' Klasse vorhanden oder haben Sie sie in einer anderen Klasse verifiziert? –

+0

@DanielOlszewski Das ist ein Fehler, jetzt korrigiert. Andere Einschränkungen arbeiten in der gleichen 'Form'-Klasse – aSemy

Antwort

0

Es gab Informationen von meinem ursprünglichen Code fehlen, speziell die Steuerung in Bezug auf, wo eine zusätzliche Validator definiert ist und gebunden. Es verwendet die falsche Methode, um den Validator einzuschließen, und überschreibt die Annotationsvalidierungen.

binder.setValidator(formValidator) überschreibt jeden anderen Validator. Stattdessen sollte binder.addValidators(formValidator) verwendet werden!

@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 
     } 
    ... 
    } 
} 

Ich habe entfernt auch den Bean MethodValidationPostProcessor in der @Configuration Klasse.

Verwandte Themen