2016-04-23 65 views
0

我想用Spring 4.2.3和HTML形式實現簡單的文件上傳。 我有控制器類處理整個行動,簡單的包裝類爲文件,驗證和簡單的視圖與形式在HTML & Thymeleaf。 幾乎所有的東西都運行良好,映射工作正常,視圖出現。但是,當我從磁盤選擇文件,並按上傳按鈕我有NullPointerException。任何人都可以看看,並提供一些技巧,請?我不得不提到,我是春季的新手。使用Spring MVC的簡單文件上傳形式的NullPointerException

控制器:

@Controller 
public class FileUploadController { 

    private static String UPLOAD_LOCATION = "C:/Temp/"; 

    @Autowired 
    FileValidator fileValidator; 

    @InitBinder("file") 
    protected void initBinderFileBucket(WebDataBinder binder) { 
     binder.setValidator(fileValidator); 
    } 

    @RequestMapping(value = "/upload", method = RequestMethod.GET) 
    public String getSingleUploadPage(ModelMap model) { 
     FileBucket fileModel = new FileBucket(); 
     model.addAttribute("fileBucket", fileModel); 
     return "views/fileUploader"; 
    } 

    @RequestMapping(value = "/upload", method = RequestMethod.POST) 
    public String singleFileUpload(@Valid FileBucket file, BindingResult result, ModelMap model) 
      throws IOException { 

     if (result.hasErrors()) { 
      System.out.println("File Uploader validation error"); 
      return "views/fileUploader"; 
     } else { 
      System.out.println("Fetching file"); //prints out in console 
      MultipartFile multipartFile = file.getFile(); 
      System.out.println(multipartFile.getName()); //NullPointer here 

      return "views/success"; 
     } 
    } 
} 

文件包:

public class FileBucket { 

    private MultipartFile file; 
    //getters & setters + soon other stuff 
} 

驗證:

@Component 
public class FileValidator implements Validator { 

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

    public void validate(Object obj, Errors errors) { 
     FileBucket file = (FileBucket) obj; 

     if(file.getFile()!=null){ 
      if (file.getFile().getSize() == 0) { 
       errors.rejectValue("file", "missingfile"); 
      } 
     } 
    } 
} 

查看:

<!DOCTYPE html> 
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" 
    xmlns:th="http://www.thymeleaf.org" 
    layout:decorator="templates/baseTemplate"> 
<head> 
<title>Upload Page</title> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
</head> 
<body> 
    <div layout:fragment="contentPanel" class="form-container"> 
     <h1>Simple upload</h1> 
     <form method="POST" enctype="multipart/form-data" action="upload" > 
      <input type="file" name="file" /> <br /> 
      <input type="submit" value="Upload" /> 
     </form> 
    </div> 
    <a href="/demo">Demo</a> 
</body> 
</html> 

堆棧跟蹤:

INFO: Starting ProtocolHandler ["http-bio-8080"] 
Fetching file 
kwi 23, 2016 12:39:36 PM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [spring] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause 
java.lang.NullPointerException 
    at web.controllers.FileUploadController.singleFileUpload(FileUploadController.java:52) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
+1

您是否正確配置了multipart支持。另外你的'@ InitBinder'不會工作,因爲你的'singleFileUpload'缺少一個'@ModeAttribute'方法,即使它不起作用,因爲你的init binder使用'fileBucker'作爲命令對象,但是你的方法需要一個命名'file'。同樣在你的驗證器中,你也可能想驗證'null'文件對象。 –

+0

謝謝你的迴應!我將'initBinder'和方法對象名更正爲'fileBucket'。我有問題然後 - 當我將它添加到'singleFileUpload'中的方法參數時,是否需要在窗體中設置任何附加屬性以匹配'@ ModelAttribute'?關於多聯支持的配置 - 我有豆在我的'ContextConfiguration': \t'@Bean \t公衆是CommonsMultipartResolver是CommonsMultipartResolver(){ \t \t回新是CommonsMultipartResolver(); \t}' – Macieyo

回答

1

好吧,我發現了什麼是造成問題。 修改@InitBinder中的名稱以匹配控制器中的參數後,必須重命名負責多部分解析的bean。

來源:

@Bean public CommonsMultipartResolver commonsMultipartResolver() { 
    return new CommonsMultipartResolver(); 
} 

要:

@Bean public CommonsMultipartResolver multipartResolver() { 
    return new CommonsMultipartResolver(); 
} 

否則這是行不通的。