java - 使用 Spring MVC 的简单文件上传形式的 NullPointerException

标签 java spring spring-mvc file-upload nullpointerexception

我正在尝试使用 Spring 4.2.3 和 HTML 表单实现简单的文件上传。 我有处理整个操作的 Controller 类、文件的简单包装类、 validator 和带有 HTML 和 Thymeleaf 表单的简单 View 。 几乎一切都运行良好, map 工作正常并且 View 正在显示。但是,当我从磁盘中选择文件并按上传按钮时,出现 NullPointerException。有人可以看一下并给一些建议吗?不得不提的是,我是 Spring 新手。

Controller :

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

validator :

@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)

最佳答案

好的,我找到了导致问题的原因。 在更正 @InitBinder 中的名称以匹配 Controller 中的参数后,有必要重命名负责多部分解析的 bean。

来自:

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

致:

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

否则它不起作用。

关于java - 使用 Spring MVC 的简单文件上传形式的 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36809184/

相关文章:

java - Java 中的加密技术保留输入文本的格式

java - 使用 Autowiring 时,抽象类对象的子类为 null

java - Rest模板拦截器

java - @NotNull 注释在 Spring boot 应用程序中不起作用

java - 如何在启动应用程序时延迟加载存储库?

java - 使用 JUnit 的内部类中的测试用例

java - 当我启动并启动时,我的应用程序崩溃了?

java - 在 Android 中的演示版和完整版之间共享保存游戏

spring - 如何在spring中使用jdbcTemplate传递多个值进行查询

java - 将 HttpServletResponse 注入(inject)服务层的最佳方式