HTML5 jQuery+FormData 异步上传文件,带进度条

利用jQuery和html5的FormData异步上传文件的好处是:

  • 实现很简单
  • 很方便地支持进度条
  • 很方便地进行扩展和美化

先看看效果图:

HTML5 jQuery+FormData 异步上传文件,带进度条_第1张图片

图片上传后的结果:

HTML5 jQuery+FormData 异步上传文件,带进度条_第2张图片


实现步骤如下:

第一步:配置好SpringMVC + servlet3.0 文件上传所需要的各种资源,参考:http://blog.csdn.net/clementad/article/details/49533189


第二步:上传页面的html代码:

[html] view plain copy print ?
  1. >
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <link href="../resources/css/common.css" rel="stylesheet" />
  6. <script src="../resources/js/jquery-2.1.4.js">script>
  7. head>
  8. <body>
  9. <h2>HTML5异步上传文件,带进度条h2>
  10. <form method="post" enctype="multipart/form-data">
  11. 其他需要提交的信息:<input type="text" name="otherInfo"/><br/><br/>
  12. 选择要上传的文件:<br/>
  13. <input type="file" name="file" /><span>span><br/>
  14. <input type="file" name="file" /><span>span><br/>
  15. form>
  16. <br/><br/>
  17. <input type="button" value="上传吧" onclick="upload()"/>
  18. <br/><br/>
  19. 上传进度:<progress>progress><br/>
  20. <p id="progress">0 bytesp>
  21. <p id="info">p>
  22. body>
  23. html>



	
	
	
	



	

HTML5异步上传文件,带进度条

其他需要提交的信息:

选择要上传的文件:






上传进度:

0 bytes



第三步:异步上传的JavaScript代码(注释很详细):

[javascript] view plain copy print ?


第四步:SpringMVC写好接受和保持文件的Controller方法:

[java] view plain copy print ?
  1. /**
  2. * 文件上传
  3. * @author XuJijun
  4. *
  5. */
  6. @RestController
  7. @RequestMapping("/servlet/file")
  8. public class FileUploadController {
  9. /**
  10. * 保存文件的目录,放在web目录、或一个指定的绝对目录下
  11. */
  12. private static final String SAVE_DIR = "uploadFiles";
  13. /**
  14. *
  15. * @param request
  16. * @param response
  17. * @param p form表单中,type="text"的input控件,内容通过这个参数传送过来,以input控件中的name属性来区分
  18. * @return JSON表示的处理结果
  19. * @throws ServletException
  20. * @throws IOException
  21. */
  22. @RequestMapping("/upload")
  23. public JsonResult upload(HttpServletRequest request, HttpServletResponse response, @RequestParam Map p)
  24. throws ServletException, IOException {
  25. // 获取 web application的绝对路径
  26. String appPath = request.getServletContext().getRealPath("");
  27. // 构造文件存放的路径
  28. String savePath = appPath + File.separator + SAVE_DIR;
  29. // 如果文件存放路径不存在,则mkdir一个
  30. File fileSaveDir = new File(savePath);
  31. if (!fileSaveDir.exists()) {
  32. fileSaveDir.mkdirs();
  33. }
  34. List fileNames = new ArrayList<>();
  35. //循环所有的part,把part中的文件保存到硬盘中
  36. for (Part part : request.getParts()) {
  37. String fileName = part.getSubmittedFileName();
  38. //form表单中的每个input,都在一个不同的part中,
  39. //所以需要判断通过fileName是否为空,过滤掉其他类型的input(比如type="text"):
  40. if(!StringUtils.isEmpty(fileName)){
  41. part.write(savePath + File.separator + fileName);
  42. fileNames.add(fileName);
  43. }
  44. }
  45. Map resultData = new HashMap<>();
  46. resultData.put("savePath", savePath);
  47. resultData.put("files", fileNames);
  48. return new JsonResult("200", "文件上传成功!", resultData);
  49. }
  50. /**
  51. * 从content-disposition头中获取源文件名
  52. *
  53. * content-disposition头的格式如下:
  54. * form-data; name="dataFile"; filename="PHOTO.JPG"
  55. *
  56. * @param part
  57. * @return
  58. */
  59. @SuppressWarnings("unused")
  60. private String extractFileName(Part part) {
  61. String contentDisp = part.getHeader("content-disposition");
  62. String[] items = contentDisp.split(";");
  63. for (String s : items) {
  64. if (s.trim().startsWith("filename")) {
  65. return s.substring(s.indexOf("=") + 2, s.length()-1);
  66. }
  67. }
  68. return "";
  69. }
  70. }
/**
 * 文件上传
 * @author XuJijun
 *
 */
@RestController
@RequestMapping("/servlet/file")
public class FileUploadController {
	
	/**
	 * 保存文件的目录,放在web目录、或一个指定的绝对目录下
	 */
	 private static final String SAVE_DIR = "uploadFiles";
	
	 /**
	  * 
	  * @param request
	  * @param response
	  * @param p form表单中,type="text"的input控件,内容通过这个参数传送过来,以input控件中的name属性来区分
	  * @return JSON表示的处理结果
	  * @throws ServletException
	  * @throws IOException
	  */
	@RequestMapping("/upload")
	public JsonResult upload(HttpServletRequest request, HttpServletResponse response, @RequestParam Map p)
			throws ServletException, IOException {

		// 获取 web application的绝对路径
		String appPath = request.getServletContext().getRealPath("");
		
		// 构造文件存放的路径
		String savePath = appPath + File.separator + SAVE_DIR;

		// 如果文件存放路径不存在,则mkdir一个
		File fileSaveDir = new File(savePath);
		if (!fileSaveDir.exists()) {
			fileSaveDir.mkdirs();
		}

		List fileNames = new ArrayList<>();
		
		//循环所有的part,把part中的文件保存到硬盘中
		for (Part part : request.getParts()) {
			String fileName = part.getSubmittedFileName();
			
			//form表单中的每个input,都在一个不同的part中,
			//所以需要判断通过fileName是否为空,过滤掉其他类型的input(比如type="text"):
			if(!StringUtils.isEmpty(fileName)){ 
				part.write(savePath + File.separator + fileName);
				fileNames.add(fileName);
			}
		}

		Map resultData = new HashMap<>();
		resultData.put("savePath", savePath);
		resultData.put("files", fileNames);
		
		return new JsonResult("200", "文件上传成功!", resultData);
	}
	 
	/**
	 * 从content-disposition头中获取源文件名
	 * 
	 * content-disposition头的格式如下:
	 * form-data; name="dataFile"; filename="PHOTO.JPG"
	 * 
	 * @param part
	 * @return
	 */
	@SuppressWarnings("unused")
	private String extractFileName(Part part) {
	    String contentDisp = part.getHeader("content-disposition");
	    String[] items = contentDisp.split(";");
	    for (String s : items) {
	        if (s.trim().startsWith("filename")) {
	            return s.substring(s.indexOf("=") + 2, s.length()-1);
	        }
	    }
	    return "";
	}

}

最后那个私有方法可以不用的,只是为了演示如何直接获取request header中的数据。


最后,验证上传过程中的网络消息:

上传的消息头和数据:

HTML5 jQuery+FormData 异步上传文件,带进度条_第3张图片
可见,对于表单中的3个input,http request payload中对应有3个part来上传数据。

关于http协议的更多介绍,可参考:http://blog.csdn.net/clementad/article/details/41620765


Controller处理后的返回结果(JSON格式):

HTML5 jQuery+FormData 异步上传文件,带进度条_第4张图片

总结:代码很简单,结果很友好。感谢HTML5和SpringMVC!


你可能感兴趣的:(HTML5 jQuery+FormData 异步上传文件,带进度条)