2016-06-09 31 views
8

Dla przesłanie pliku Próbuję wstrzyknąć i używać walidatora w moim wiosennym kontrolera tak:.

@RestController 
@RequestMapping("/api") 
public class FileController{ 

    @Autowired 
    private MessageSource messageSource; 

    @Autowired 
    FileValidator validator; 

    @InitBinder("file") 
    public void initBinderFile(WebDataBinder binder) { 
     binder.setValidator(validator); 
    } 

    @RequestMapping(value = "/fileUpload2", method = RequestMethod.POST, produces = {"text/plain"}) 
    @PreAuthorize("hasAuthority('ADMINISTRATOR')") 
    public String singleFileUpload2(@Valid @ModelAttribute("file") File file, BindingResult result) throws IOException { 
     if (result.hasErrors()) { 
      String errorString = ""; 
      for (ObjectError error : result.getAllErrors()) { 
       errorString = errorString.concat(messageSource.getMessage(error.getCode(), new String[]{}, Locale.ENGLISH)+"\n"); 
      } 
      return errorString; 
     } else { 
      MultipartFile multipartFile = file.getFile(); 

      String fileName = multipartFile.getOriginalFilename(); 
      System.out.println("Fetching file: "+fileName); 

      return messageSource.getMessage("upload.file.success", new String[]{}, Locale.ENGLISH); 
     } 
    } 

} 

Oto moja Validator:

@Component 
public class FileValidator implements Validator { 

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

    @Override 
    public void validate(Object obj, Errors errors) { 
     File file = (File) obj; 

     if (file.getFile().getSize() == 0) { 
      errors.rejectValue("file", "missing.file"); 
     } else try { 
      if (file.getFile().getBytes().length > 2097152l) { 
       errors.rejectValue("file", "upload.file.error.size"); 
      } 
      if(!file.getFile().getContentType().equalsIgnoreCase("text/html")){ 
       errors.rejectValue("file", "incorrect.file.type"); 
      } 
     } catch (IOException ex) { 
      errors.rejectValue("file", "upload.file.error"); 
     } 
    } 
} 

Oto obiekt File że staram się potwierdzić:

public class File { 

    private String name; 
    private MultipartFile file; 

    public File() { 
    } 

    public File(MultipartFile file) { 
     this.file = file; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public MultipartFile getFile() { 
     return file; 
    } 

    public void setFile(MultipartFile file) { 
     this.file = file; 
    } 

} 

I tu jest błąd, który pojawia się przy próbie uruchomienia moje Zgłoszenie kation:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'fileController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.enterprise.springapp.web.validators.FileValidator com.eurodyn.springapp.web.FileController.validator; nested exception is java.lang.IllegalArgumentException: Can not set com.enterprise.springapp.web.validators.FileValidator field com.enterprise.springapp.web.FileController.validator to com.sun.proxy.$Proxy101 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:766) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:361) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.5.RELEASE.jar:1.3.5.RELEASE] 
    at com.enterprise.springapp.SpringApp.main(SpringApp.java:30) [classes/:na] 
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.enterprise.springapp.web.validators.FileValidator com.enterprise.springapp.web.FileController.validator; nested exception is java.lang.IllegalArgumentException: Can not set com.enterprise.springapp.web.validators.FileValidator field com.enterprise.springapp.web.FileController.validator to com.sun.proxy.$Proxy101 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:573) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    ... 17 common frames omitted 
Caused by: java.lang.IllegalArgumentException: Can not set com.enterprise.springapp.web.validators.FileValidator field com.enterprise.springapp.web.FileController.validator to com.sun.proxy.$Proxy101 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) ~[na:1.8.0_45] 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171) ~[na:1.8.0_45] 
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[na:1.8.0_45] 
    at java.lang.reflect.Field.set(Field.java:764) ~[na:1.8.0_45] 
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569) ~[spring-beans-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    ... 19 common frames omitted 
2016-06-09 15:12:39.909 WARN 4896 --- [   main] o.s.boot.SpringApplication    : Error handling failed (Error creating bean with name 'delegatingApplicationListener' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry' is defined) 

Nie wiem, co się dzieje. Czy ktoś może pomóc?

+1

1. Nigdy nie używaj opcji '@ Autowired' na polach. 2. Istnieje konfiguracja bezpieczeństwa sieci, więc nie ma większego sensu umieszczanie '@PreAuthorize (" hasAuthority ('ADMINISTRATOR') ") w metodzie sterownika. Połączenie tych dwóch punktów jest przyczyną twojego problemu. – zeroflagL

+0

@zeroflagL są to dość ogólne stwierdzenia. Obie rzeczy, które sprzeciwiają się mieć swoje miejsce. – OrangeDog

+0

@OrangeDog Deweloperzy Springa sami zniechęcają do używania '@ Autowired' na polach. Ale jeśli masz na to miejsce, to oczywiście możesz z niego korzystać. – zeroflagL

Odpowiedz

14

Nie można ustawić pole 'FileValidator' 'FileController.validator' do 'com.sun.proxy. $ Proxy101'

FileValidator jest klasą, a nie interfejs.

com.sun.proxy.$Proxy101 to proxy interfejsu, a nie proxy klasy.

Istnieją dwa główne sposoby rozwiązania tego problemu. Albo wstrzykiwać weryfikator za pośrednictwem interfejsu, na przykład:

@Autowired @Qualifier("fileValidator") 
private Validator fileValidator; 

lub włączyć CLASS proxy, na przykład:

@SpringBootApplication 
@EnableAspectJAutoProxy(proxyTargetClass = true) 
public class Application { 

Są to tylko przykłady, nie będzie innych sposobów realizacji obu tych rozwiązań.

+1

Dziękuję bardzo za pomoc! Zastosowałem drugie rozwiązanie i zadziałało. – FunnyJava

+0

Problem nie dotyczy 'FileValidator', ale' FileController'. – zeroflagL

+0

@zeroflagL problemem jest to, jak się oddziałują - to nie tylko jedno czy drugie. – OrangeDog

0

Autowire interfejs FileValidator(class) w klasie FileController. Wykonanie tej czynności nie wymaga określenia parametru @ jak podano poniżej:

@Autowired 
IFileValidator filevalidator;