javaspringapache-commons-fileupload

Problem while uploading file in Spring with apache-commons-fileupload


I'm trying to upload an image in a web application built on Spring MVC using local tomcat container, but the code continue to throw a NullPointerException.

I already searched the net for tutorials but none of them worked, in particular i followed the one provided by webSystique, Baeldung and mkyong sites. Everything goes well, including validation, until it comes to fetch the file.
So the Spring configuration and the webapp are correct, as far as I can understand, except for the upload part shown below.

This is the code in AppConfig.java to configure MultipartResolver for apache-commons:

@Bean
public CommonsMultipartResolver getResolver() throws IOException{

    CommonsMultipartResolver resolver = new CommonsMultipartResolver();
    resolver.setMaxUploadSize(5242880); //max file size set to 5MB

    return resolver;
}

This is the model Image.java file which represent the file:

public class Image {

private MultipartFile profilePicture;

public MultipartFile getProfilePicture() {
    return profilePicture;
}

public void setProfilePicture(MultipartFile profilePicture) {
    this.profilePicture = profilePicture;
}
}

Controller method that redirect to form:

@RequestMapping(value = "/upload-{id}", method = RequestMethod.GET)
public String uploadPage(ModelMap model){

    Image image = new Image();
    model.addAttribute("image", image); //set attribute to request map

    return "uploadForm";
}

The form code in the uploadForm.jps page:

        <form:form method="POST" modelAttribute="image" enctype="multipart/form-data">
            <div class="row">
                <div class="form-group col-md-12">
                    <div class="col-md-7">
                        <form:input path="profilePicture" type="file" id="profilePicture"></form:input>
                        <form:errors path="profilePicture" cssClass="text-danger"></form:errors>
                    </div>
                </div>
            </div>
            <div class="row">
                <input type="submit" value="upload" class="btn btn-primary btn-sm">
            </div>
        </form:form>

and last, the method mapped to upload the file in the new path:

@RequestMapping(value = "/upload-{id}", method = RequestMethod.POST)
public String fileUpload(@Valid Image profilePicture, BindingResult result, @PathVariable int id, ModelMap model) throws IOException {

    if(result.hasErrors()){ //in case of validation error redirect to form page
        return "uploadForm";
    }

    MultipartFile multipartFile = profilePicture.getProfilePicture();

    byte[] source = multipartFile.getBytes(); //source file bytes array
    File dest = new java.io.File(UPLOAD_LOCATION + profilePicture.getProfilePicture().getOriginalFilename()); //destination file
    //copying the file to the new position
    FileCopyUtils.copy(source, dest);

    String fileName = multipartFile.getOriginalFilename(); //original name of file got and saved in attributes map
    employeeService.updateImage(id, fileName);
    model.addAttribute("fileName", fileName);

    return "fileUploaded";
}

The UPLOAD_LOCATION is defined inside the controller class with the line:

private static final String UPLOAD_LOCATION = "C:/EmployeeManager/";

and the O.S. is windows.

The exception is thrown in the fileUpload method in the subsequent line:
byte[] source = multipartFile.getBytes(); //source file bytes array

This is the root cause shown by the log:

java.lang.NullPointerException
employeeManager.controller.FileController.fileUpload(FileController.java:80)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

Solution

  • Your problem is caused by a NullPointerException so the solution to your problem is quite simple, make sure that you are not trying to access members of a null object.

    The exception is thrown at line 80 and you have already determined that yourself:

    java.lang.NullPointerException
    employeeManager.controller.FileController.fileUpload(FileController.java:80)
    
    byte[] source = multipartFile.getBytes(); //source file bytes array
    

    So just make sure that neither multipartFile nor profilePicture objects are null before they are accessed. According to your stacktrace the problem is one of those two variables.