Mr Morgan
Mr Morgan

Reputation: 2243

File upload in Spring MVC gives NullPointerException

I have a simple JSP form as follows:

<p>Please select a file and <i>click</i> <i>Upload file</i> to upload the file to the server:</p>
    <c:url value="/upload/display" var="displayUploadedFileURL" />                   
    <form:form action="${displayUploadedFileURL}" method="post" modelAttribute="upload" enctype="multipart/form-data">            
        <input type="file" name="file" />                       
        <input type="submit" value="Upload file" />&nbsp;<form:errors path="file" />
        <input type="Reset" value="Reset">           
    </form:form>         

Which is for a user to upload a file to the server. The controller's method is as follows:

@Controller
@RequestMapping("/upload")
public class UploadController {

@Autowired
private UploadValidator uploadValidator; 



    @RequestMapping(value="/display", method=RequestMethod.POST)
    public String displayUploadedFile(@ModelAttribute("upload") Upload upload,
                                      BindingResult bindingResult,
                                      Model model) {                

        // Validate Upload.
        uploadValidator.validate(upload, bindingResult);
        if (bindingResult.hasErrors()) {  
            return ("view/upload/select");  
        }
        else {
            String fileName = upload.getFile().getOriginalFilename();
            System.out.println("Here: " + upload.getFile().getOriginalFilename());            
            model.addAttribute("fileName", fileName);
            return ("view/upload/display");
       }       
   }  

...

But when I select a file and use the Upload file button I get the following:

Your page request has caused a NullPointerException: error:

library.validator.UploadValidator.validate(UploadValidator.java:29)
library.controller.upload.UploadController.displayUploadedFile(UploadController.java:45)

The validator concerned is very simple:

package library.validator;

import library.model.Upload;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

@Component
public class UploadValidator implements Validator {

private static final Logger logger = Logger.getLogger(UploadValidator.class);   

public UploadValidator() {
}

@Override
public boolean supports(Class cls) {
    return Upload.class.isAssignableFrom(cls);
}

@Override
public void validate(Object target, Errors errors) {
    logger.info(UploadValidator.class.getName() + ".validate() method called.");  

    Upload upload = (Upload) target;
    if (upload.getFile().getSize() == 0) {
        errors.rejectValue("file", "file.required");
    }       
}            

}

I have all the relevant .jar files in the application's .lib folder, and I'mincluding the following:

<bean id="uploadValidator" class="library.validator.UploadValidator" />        

<!-- Spring multipartResolver. -->         
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />  

In the DispatcherServlet.

The Upload object type is as follows:

import org.springframework.web.multipart.MultipartFile;

public class Upload {

    private MultipartFile file;

And appropriate getter and setter.

So why is my code not working?

Stacktrace for current problem, i.e. allowing for changes to controller method in answer below, is:

org.springframework.util.Assert.notNull(Assert.java:112) org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.resolveName(RequestParamMethodArgumentResolver.java:171) org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:89) org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:79) org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:157) org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:124) 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:690) org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) 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:641) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) javax.servlet.http.HttpServlet.service(HttpServlet.java:722) org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304) org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240) org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:498) org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100) org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:562) org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:394) org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166) org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread.java:744)

Upvotes: 3

Views: 2996

Answers (2)

Stepan Tuhacek
Stepan Tuhacek

Reputation: 218

Configuring the multipartResolver bean is important thing, but also you should check that your .xml config file with this bean is imported in your general applicationContext.xml, if you have some. I had same problem and this did the thing.

Upvotes: 1

Mr Morgan
Mr Morgan

Reputation: 2243

This has now been solved. The problem was that the following was incorrectly defined in the DispatcherServlet:

<!-- Spring multipartResolver. -->         
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

Upvotes: 0

Related Questions