Spring Boot file upload with Ajax

In this post is shown how to uploading a file (e.g. an image) using Ajax with a Spring Boot web application server side. JQuery will be used client-side to simplify our life.

Html form

The following is the minimal html form for file uploading:

<!-- Upload file form -->
<form id="upload-file-form">
  <label for="upload-file-input">Upload your file:</label>
  <input id="upload-file-input" type="file" name="uploadfile" accept="*" />
</form>

Javascript

With a javascript code we bind the on-change event for the input element (that will be triggered when a file is chosen) and we send the file to the server with an Ajax POST using a FormData object.

// bind the on-change event
$(document).ready(function() {
  $("#upload-file-input").on("change", uploadFile);
});

/**
 * Upload the file sending it via Ajax at the Spring Boot server.
 */
function uploadFile() {
  $.ajax({
    url: "/uploadFile",
    type: "POST",
    data: new FormData($("#upload-file-form")[0]),
    enctype: 'multipart/form-data',
    processData: false,
    contentType: false,
    cache: false,
    success: function () {
      // Handle upload success
      // ...
    },
    error: function () {
      // Handle upload error
      // ...
    }
  });
} // function uploadFile

Spring Boot controller

Server side we need a Spring Boot controller listening for an HTTP POST at the url /uploadFile. The controller’s method handle the uploaded file saving it locally in the filesystem.

/**
 * POST /uploadFile -> receive and locally save a file.
 * 
 * @param uploadfile The uploaded file as Multipart file parameter in the 
 * HTTP request. The RequestParam name must be the same of the attribute 
 * "name" in the input tag with type file.
 * 
 * @return An http OK status in case of success, an http 4xx status in case 
 * of errors.
 */
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
@ResponseBody
public ResponseEntity<?> uploadFile(
    @RequestParam("uploadfile") MultipartFile uploadfile) {
  
  try {
    // Get the filename and build the local file path (be sure that the 
    // application have write permissions on such directory)
    String filename = uploadfile.getOriginalFilename();
    String directory = "/var/netgloo_blog/uploads";
    String filepath = Paths.get(directory, filename).toString();
    
    // Save the file locally
    BufferedOutputStream stream =
        new BufferedOutputStream(new FileOutputStream(new File(filepath)));
    stream.write(uploadfile.getBytes());
    stream.close();
  }
  catch (Exception e) {
    System.out.println(e.getMessage());
    return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
  }
  
  return new ResponseEntity<>(HttpStatus.OK);
} // method uploadFile

Some configurations

Spring Boot takes some optional configurations in order to limit file sizes. You can put them in the application.properties file.

src/main/resources/application.properties
# Set the file size limit (default 1Mb). If you want to specify that files be 
# unlimited set the multipart.maxFileSize property to -1.
multipart.maxFileSize = 3Mb

# Set the total request size for a multipart/form-data (default 10Mb)
multipart.maxRequestSize = 20Mb

Try yourself

You can try the above code getting it from our github repository:

https://github.com/netgloo/spring-boot-samples/tree/master/spring-boot-file-upload-with-ajax

References

https://spring.io/guides/gs/uploading-files/

http://hmkcode.com/spring-mvc-upload-file-ajax-jquery-formdata/

http://pauliusmatulionis.blogspot.it/2013/10/spring-mvc-ajax-file-upload.html

http://portfolio.planetjon.ca/2014/01/26/submit-file-input-via-ajax-jquery-easy-way/

  • Aravind Pilla

    Hi I need to send data like(name,email,phoneno) along with the image all the things should be captured into the bean on the controller side..can u please help me with this

    • Take a look at the first reference (https://spring.io/guides/gs/uploading-files/ ), there is an example that sends an html text input (name) along with the file… It should works simply adding a RequestParam in your controller handling others inputs, but I didn’t tried it.. Let me know if you make a try.

  • Phumzile F Saleni

    how do you handle the error thrown when the file uploaded is bigger than 3mb

  • Chawqi Hajar

    Thank you for your post , in my case i have to upload the files in static/FilesStore , so what i have done is this
    String filename = file.getOriginalFilename();
    String directory = “/FilesStore”;
    String filepath = Paths.get(directory, filename).toString();

    BufferedOutputStream stream =
    new BufferedOutputStream(new FileOutputStream(new File(filepath)));
    stream.write(bytes);
    stream.close(); But it gives me an error but when i change aa location to a local one like F:/ , it works , what am i doing wrong?

    • Take a look here http://stackoverflow.com/a/20720866 or here http://stackoverflow.com/a/19923744 and try to use the ServletContext to get the current path of your web application.

      However I discourage you to saving files inside your web application, it’s better to keep well separated the application itself from its contents. It will be simple to maintain and update in the production environment.

      • Chawqi Hajar

        Thank you but how can i save the files in tomcat server without creating a folder in static . i am really confused .Can you help?

        • You should save files outside the web server, e.g. in /var/netgloo_blog/uploaded_files/.

          If your problem is how to serve such files, you can create a controller responding for example on the url /files/{filename}, then inside this controller you return your file reading it from the filesystem, using a function like this:


          public byte[] getFile(String name) throws IOException {
          Path filePath = Paths.get("/var/netgloo_blog/uploaded_files/", name);
          return Files.readAllBytes(filePath);
          }

          • Chawqi Hajar

            Okay thank you so much

  • Aghil krishna

    I am trying to solve this issue but still i can’t. I tried above solution by modifying my project even though it’s not working. I really need your help in this. I have included the common-io & fileupload in my dependencies too .here is my code :

    SPRING BOOT STARTED FILE : (in groovy)

    @SpringBootApplication
    class BookTestApplication {

    static void main(String[] args) {
    SpringApplication.run BookTestApplication, args
    }

    @Bean
    public FacesServlet facesServlet() {
    return new FacesServlet();
    }

    @Bean
    public ServletRegistrationBean facesServletRegistration() {
    ServletRegistrationBean registration = new ServletRegistrationBean(facesServlet(), “*.xhtml”);
    registration.setName(“FacesServlet”);
    return registration;
    }

    @Bean
    public ServletListenerRegistrationBean jsfConfigureListener() {
    return new ServletListenerRegistrationBean(new ConfigureListener());
    }

    @Bean
    public ServletContextInitializer initializer() {
    return new ServletContextInitializer() {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
    servletContext.setInitParameter(“javax.faces.FACELETS_SKIP_COMMENTS”, “true”);
    servletContext.setInitParameter(“primefaces.UPLOADER”,”commons”);
    }
    };
    }

    WEB.XML FILE :

    Faces Servlet
    javax.faces.webapp.FacesServlet

    PrimeFaces FileUpload Filter
    org.primefaces.webapp.filter.FileUploadFilter

    PrimeFaces FileUpload Filter
    Faces Servlet

    primefaces.UPLOADER
    commons

    BEAN FILE : (in groovy)

    @Scope(“session”)
    class FileBean {

    UploadedFile uploadedFile;

    public void upload()
    {
    println “hiii upload”
    println uploadedFile
    if(uploadedFile != null) {
    println “filename : “+uploadedFile.fileName
    println “filename : “+uploadedFile.size
    }
    }

    public void handleFileUpload(FileUploadEvent event) {
    println “linstener here”
    uploadedFile = event.getFile();
    println uploadedFile
    }

    HTML FILE :

    • Hi Aghil. I’m sorry, but your code seems very different from that in my post. I don’t know how to help you.
      Did you tried to post a question about your problem on stackoverflow?

      • Aghil krishna

        Hi Andrea,

        Thanks for your reply. I already post my question in stackoverflow but no reponse yet. Actually you tried to upload file through rest controller. In mine, i tried to upload to file through bean class.

        I removed the enctype from my form to check whether the bean class method getting called or not and the method getting called

        But when i mentioned the enctype in my form so that the file will bind with the request and send to the method, this time the method is not getting called.

        I will try to implement it in rest controller and let you know. Meanwhile if you sort out the problem. please update me . thank you again.

      • Aghil krishna

        Hi Andrea,

        I tried to upload file through rest mode and its works fine. Thanks for your help brother. And i will also check how to upload file through bean and update you.

  • Jiten Shahi

    can i use this in android app development? for printing submitted form details in spring boot console? or can u explain me how i print my android app form submitted details in spring boot console?

    • Hi Jiten. Do you want receive the form on the android app or do you want send a form from android to a web server (running spring boot)?

      • Jiten Shahi

        hey Andrea.

        my question is -> you can submit the registration or login form from Android App and you should then print the submitted value in SpringBoot console using System.out.

        and please give me a explaination so i can understand because i am new in this field….-:)

        • Sorry, but I have not experience with Android apps. But, server side (where is Spring Boot) you can receive an HTTP POST request and to do that you can see simpler examples than mine, like this one. From the Android app you should simply send a HTTP POST to your server and to do that I would take some ideas from here or here.
          Finally, if can help you, in this post I described how you can print some logs in the spring boot console.

  • Abel abelique

    Hard work and well explained. Thanks
    would be great for you, an example of how ManyToOne relations with spring boot etc are handled.
    I would like to return a category each with its products that you own. Seller faultless jackso.
    Thanks.

  • Jakkarin

    How to insert path in DB ?

  • Chandra Chandra

    how to upload file base64 using boot thanks

Categories

Category BootstrapCategory CoffeescriptCategory DrupalCategory GravCategory HTMLCategory JavascriptCategory JoomlaCategory jQueryCategory LaravelCategory MagentoCategory PHPCategory SharePointCategory SpringCategory ThymeleafCategory WordPressCategory Workflow

Comments

Developed and designed by Netgloo
© 2016 Netgloo