0

I am trying to implement simple fileupload using Spring 4.2.3 and HTML form. I have controller class which handles whole action, simple wrapper class for file, validator and simple view with form in HTML & Thymeleaf. Almost everything is running fine, mapping works properly and view is appearing. But when I select file from disk and press upload button I have NullPointerException. Can anyone have a look and give some tips please? I have to mention that I am novice in 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";
        }
    }
}

File wrapper:

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");
            }
        }
    }
}

View:

<!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>

Stacktrace:

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)
2
  • 1
    Have you correctly configured multipart support. Also your @InitBinder won't work because your singleFileUpload is missing a @ModelAttribute method and even then it wouldn't work as your init binder uses fileBucker as a command object, but your method expects one named file. Also in your validator you probably want to validate for a null file object as well. Commented Apr 23, 2016 at 10:59
  • Thank you for response! I corrected initBinder and method object name to fileBucket. I have question then - do I need to set any additional attribute in form to match @ModelAttribute when I add it to a method argument in singleFileUpload? Concerning configuration of multipart support - I have Bean in my ContextConfiguration: @Bean public CommonsMultipartResolver commonsMultipartResolver() { return new CommonsMultipartResolver(); } Commented Apr 23, 2016 at 11:21

1 Answer 1

1

Okay I found out what's causing the problem. After correcting name in @InitBinder to match argument in controller it was necessary to rename bean responsible for multipart resolving.

From:

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

To:

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

Otherwise it doesn't work.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.