You can upload files to Spring MVC app in many different ways. For the server side, using MultipartHttpServletRequest is the easiest way to get uploaded files. For the client side we have different options, traditional synchronous method “using html form with submit” or asynchronous method by using Ajax.
Similar Post: Spring MVC + jQuery File Upload (multiple, drag&drop, progress…)
Objectives:
- How to receive uploaded files “Multipart” using Spring MVC?
- How to upload files synchronously “HTML Form and Submit Button”?
- How to upload files asynchronously using JQuyer.ajax or FormData object?
Environment:
- Eclipse
- Jetty (or any java server)
- Firefox or Chrome
Libraries:
Source Code @ github
( 1 ) Java Project
( 2 ) Server Side (Java & XML)
- RestController.java: Spring MVC controller with two method get & upload.
- upload() receive the upload file. Notice the MultipartHttpServletRequest class which we are using to get files out of the request object.
- get() retrieve last upload file.
package com.hmkcode.controllers; import java.io.IOException; import java.util.Calendar; import java.util.Iterator; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.util.FileCopyUtils; import com.hmkcode.vo.UploadedFile; @Controller @RequestMapping("/cont") public class RestController { UploadedFile ufile; public RestController(){ System.out.println("init RestController"); ufile = new UploadedFile(); } @RequestMapping(value = "/get/{value}", method = RequestMethod.GET) public void get(HttpServletResponse response,@PathVariable String value){ try { response.setContentType(ufile.type); response.setContentLength(ufile.length); FileCopyUtils.copy(ufile.bytes, response.getOutputStream()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @RequestMapping(value = "/upload", method = RequestMethod.POST) public @ResponseBody String upload(MultipartHttpServletRequest request, HttpServletResponse response) { //0. notice, we have used MultipartHttpServletRequest //1. get the files from the request object Iterator<String> itr = request.getFileNames(); MultipartFile mpf = request.getFile(itr.next()); System.out.println(mpf.getOriginalFilename() +" uploaded!"); try { //just temporary save file info into ufile ufile.length = mpf.getBytes().length; ufile.bytes= mpf.getBytes(); ufile.type = mpf.getContentType(); ufile.name = mpf.getOriginalFilename(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //2. send it back to the client as <img> that calls get method //we are using getTimeInMillis to avoid server cached image return "<img src='http://localhost:8080/spring-mvc-file-upload/rest/cont/get/"+Calendar.getInstance().getTimeInMillis()+"' />"; } }
- UploadedFile.java : just a helper class to store property of last uploaded file such as name, length, bytes…
package com.hmkcode.vo; public class UploadedFile { public int length; public byte[] bytes; public String name; public String type; }
- rest-servlet.xml : Spring context configuration file.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <context:component-scan base-package="com.hmkcode.controllers" /> <mvc:annotation-driven /> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/> </beans>
- web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>SpringMVC</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> </welcome-file-list> <servlet> <servlet-name>rest</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>rest</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> </web-app>
( 3 ) Client Side (index.html)
- index.html : I splitted the file for better readability!
- Make sure to change the URL used in the index.html as appropriate.
- refer to github for complete file
- We need to import two javascript libraries.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Spring MVC - Upload File</title> <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://malsup.github.com/jquery.form.js"></script>
- Build function to send ajax request using jquery form plugin.
//using jquery.form.js function uploadJqueryForm(){ $('#result').html(''); $("#form2").ajaxForm({ success:function(data) { $('#result').html(data); }, dataType:"text" }).submit(); }
- Build another javascript function to make ajax request. The body of the request will be the FormData object. Read more about FormData…
//using FormData() object function uploadFormData(){ $('#result').html(''); var oMyForm = new FormData(); oMyForm.append("file", file2.files[0]); $.ajax({ url: 'http://localhost:8080/spring-mvc-file-upload/rest/cont/upload', data: oMyForm, dataType: 'text', processData: false, contentType: false, type: 'POST', success: function(data){ $('#result').html(data); } }); }
- Create two html forms one for the synchronous request and the other for the ajax request
<body> <h1>SpringMVC - File Upload with/without Ajax</h1> <!-- Form 1 --> <i>Uploading File Without Ajax</i><br/> <form id="form1" method="post" action="/spring-mvc-file-upload/rest/cont/upload" enctype="multipart/form-data"> <!-- File input --> <input name="file" id="file" type="file" /><br/> <input type="submit" value="Upload" /> </form> <hr/>
<!-- Form 2 --> <i>Uploading File With Ajax</i><br/> <form id="form2" method="post" action="/spring-mvc-file-upload/rest/cont/upload" enctype="multipart/form-data"> <!-- File input --> <input name="file2" id="file2" type="file" /><br/> </form> <button value="Submit" onclick="uploadJqueryForm()" >Upload</button><i>Using JQuery Form Plugin</i><br/> <button value="Submit" onclick="uploadFormData()" >Upload</button><i>Using FormData Object</i> <div id="result"></div> </body> </html>
( 3 ) Run
- Run Jetty or your java server
- Go to http://localhost:8080/spring-mvc-file-upload
- The sample is designed to upload images, however it can be used to upload any file type.
- If you upload an image without using Ajax, you will see the the uploaded the image in a new page.
- If you upload an image with Ajax, you will see the uploaded image at the bottom of the page.
Similar Post: Spring MVC + jQuery File Upload (multiple, drag&drop, progress…)