背景介紹:公司要在CMS系統上為運營人員提供一個功能供運營人員將做好的活動頁面上傳到阿里雲存儲上,上傳的內容為一個文件夾,文件夾內部有.html網頁,JS文件夾下有JS文件,CSS文件夾下有樣式表,Images文件夾下有多張圖片,具體的目錄接口如下;

要在網頁上將整個文件夾進行上傳,下面介紹下我整個實現的過程。
項目架構,前端使用的JSP,后端使用的Jersey,一個類似WebService的技術。
直接上代碼,前端JSP文件:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@include file="/Web/common/page/jqueryMaster_new.jsp"%> <!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=UTF-8"> <title>文件夾上傳</title> </head> <body> <div id="content"> <h1>使用本功能時請使用谷歌瀏覽器</h1> <div style="clear:both;content:'';"></div> <br> <br> <u><font size="24">按照文件夾進行上傳的功能只被個別瀏覽器支持,如谷歌,Microsoft Edge瀏覽器</font></u> <div style="clear:both;content:'';"></div> <br> <br> <form action="<%=url%>/v1/operation/uploadFolder" method="post" name="fileUploadForm" id="fileUploadForm" enctype="multipart/form-data"> <input name="fileFolder" type="file" webkitdirectory> <input type="submit" name="subButton" value="提交"> </form> </div> </body> </html>
需要特別說明的是:並不是全部的瀏覽器都支持按照文件夾進行上傳,目前只有谷歌瀏覽器還有Microsoft Edge支持按照文件夾進行上傳,具體可以看下百度雲盤的網頁版的上傳按鈕,在火狐下就支持按照文件進行上傳,而在谷歌和Edge下,就會給用戶提供一個下拉,讓用戶選擇是根據文件進行上傳還是根據文件夾進行上傳。
而在谷歌瀏覽器下,也不是沒有條件的支持,必須在input上加入一個屬性:webkitdirectory后才會予以支持。
后端代碼也比較簡單,但是必須注意的是,如果按照文件夾進行上傳,后端就不能獲取流,而是要獲取整個表單。后端使用的是Jersey,想來使用其他技術應該也是一樣的,只要能獲取整個表單即可。
package com.bomei.services; import java.io.InputStream; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import org.apache.log4j.Logger; import org.springframework.stereotype.Service; import com.bomei.util.Toolkit; import com.bomei.util.UploadUtils; import com.sun.jersey.core.header.FormDataContentDisposition; import com.sun.jersey.multipart.FormDataBodyPart; import com.sun.jersey.multipart.FormDataMultiPart; /** * 運營功能服務類 * */ @Path("/v1/operation") @Service public class OperationService { private Logger logger = Logger.getLogger(getClass()); @POST @Path("/uploadFolder") @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) public String uploadFileFolder( @Context HttpServletRequest request, FormDataMultiPart fileUploadForm) { StringBuffer buffer = new StringBuffer().append("\n\n\n"); //初始化本次上傳的文件夾名 String curUploadFolderName = "operation/"+String.valueOf(Toolkit.getCurrentTime()); System.out.println("本次上傳創建的文件夾路徑為:"+curUploadFolderName); List<FormDataBodyPart> filePartList = fileUploadForm.getFields("fileFolder"); if(null != filePartList){ for (FormDataBodyPart part : filePartList) { InputStream inputStream = part.getValueAs(InputStream.class); FormDataContentDisposition detail = part.getFormDataContentDisposition(); MediaType type = part.getMediaType(); String contentType = type.getType() + "/" + type.getSubtype(); String fileName = detail.getFileName(); //截取第一個/之后的路徑地址 int indexOf = fileName.indexOf("/"); if(indexOf > 0){ fileName = curUploadFolderName + fileName.substring(indexOf); }else{ fileName = curUploadFolderName + fileName; } //開始上傳操作 String path = UploadUtils.uploadFile(fileName, inputStream, contentType);//內部上傳邏輯,你可以上傳到你想要上傳的任何位置 buffer.append(" ") .append("文件名稱 ").append(detail.getFileName().trim()).append(" ").append("文件路徑 ").append(path).append("\n"); } }else{ System.out.println("獲取上傳的文件夾內容失敗,或者文件夾中不存在文件"); } logger.info("運維上傳的內容為:"+buffer.toString()); System.out.println("運維上傳的內容為:"+buffer.toString()); return buffer.toString(); } }
具體的上傳方法沒有貼出來,你可以自己實現,或者百度,我內部是上傳到了阿里雲上。
至此整個文件夾上傳操作就完成了,有兩點需要注意的再次提一下:
1:並不是所有的瀏覽器都支持按照文件夾進行上傳,需要添加必要的屬性;
2:后端代碼要獲取的不是流對象,而是整個表單對象,這樣才能遍歷上傳的文件夾。
