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

          • David

            Hi. Andrea. Thanks for your post.

            Could you please tell how to manage this situation about where to save the files.
            In production enviroment normally you deploy the web application in a tomcat server (my case) and it should work without create folders in that system (eg: ubuntu server, windows server, etc.. ) Usually you don’t have access or permission.
            Thanks, works great!!

          • Hello David, probably there is not a right answer suitable for any situation. Anyway I think that for web applications a nice place is a storage folder placed in the project’s root directory. When you save the file you should retrieve the path of such folder dynamically or save the path within the configuration file (application.properties). If you are using git you should add such folder in the .gitignore.

            Take a look here also for some interesting best practices: http://stackoverflow.com/a/18664715/3763649

          • David

            Great!!!!
            Thanks for the info.

          • its work! tkss

  • 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

  • andretti1977

    Thanks, brief and perfect post!

    Just a note, as you can find on Spring Boot file upload tutorial, the correct properties name for file upload limits are:

    spring.http.multipart.max-file-size=128KB
    spring.http.multipart.max-request-size=128KB

    • Thank you. I will update the post.

  • Herculano Cunha

    I can upload, but can’t get image after upload spring boot using angularjs, only after application restart.

    • Hello Herculano, better you ask on StackOverflow about your issue, giving more details as possible (your project structure, where you are saving the file, the log if you are getting some errors).
      You can leave here a link to your question on StackOverflow so I will take a look if I’m able to help you.

  • wided ben abdallah

    I tried to test this rest controller with postman in order to use the link in angular2 , but i’m gettin’ this error. So please can you help me to resolve this problem.

    https://uploads.disquscdn.com/images/3579ba07de52e26e314576a47a6b2339eb9e4c055538f7e12f4b870267f6c0e0.png

    • Hello, please use Stackoverflow for problems (then you can leave a comment here with the link to your question on Stackoverflow).

      You can also try to take a look to this question, seems to have your same problem, maybe it’s useful for you: http://stackoverflow.com/questions/40488585/postman-required-request-part-file-is-not-present

      • wided ben abdallah

        Thanks, but this didn’t solve my problem. I followed the exact controller u’re putting here without sing the html and the script. So i’ve said that maybe there is some changes i need to make in order to test this

  • Dedy

    i always error if i use angular2. is it my angular2 code error, or perhaps i have to change to backend code?

  • Nicholas

    Whichever file I choose, I get the “File not uploaded (perhaps it’s too much big)” message. I’m pretty much of a novice, where do I go wrong, please?

    • Hello Nicholas, maybe the folder /var/netgloo_blog/uploads doesn’t exists on your system. Try to open the application.properties file and change this path with a valid directory (and be sure you have write permission on it.

  • Waqas Rana

    how can we upload multiple files there?

    • Hi Waqas, sadly I’ve never done that so I can’t help you very much. Anyway, I would try to use this on server side: @RequestParam List files (as in here or here) and sending data via ajax in a way similar to this here.
      I’m sorry I can’t help you more than this.
      You can try to ask on Stackoverflow, linking the github repo and posting what you have tried so far.
      Good luck anyway! 🙂

  • David

    Hi.
    I have been trying to adapt your example as described in:
    https://stackoverflow.com/questions/47006087/multiples-file-uploads-with-differents-id-in-a-table

    but not be able. Could you please take a look, maybe you can help me.

    Thanks

    • Hello David,
      Ok I will take a look.
      Thank you.

  • Deepa R

    Hi,
    can i curl the data??
    like : curl -F uploadfile=@”/home/1.png” http://localhost:8080/

Categories

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

Comments

Developed and designed by Netgloo
© 2019 Netgloo