java web 一行程式碼實現檔案上傳下載
每當要實現檔案上傳下載的功能時,都要複製貼上拼湊程式碼。如果用了不同的框架,程式碼還不一樣,配置啥的一堆,甚是繁瑣,不喜歡。科學家們喜歡把紛繁複雜的自然現象總結為一個個簡潔的公式,我們也來試試,把上傳下載整成一行程式碼~
花了一天時間,整了個通用的工具類FileUtils,這個類裡實際只包含兩個靜態方法,一個上傳upload(),一個下載download()。只依賴apache的commons-fileupload.jar和commons-io.jar,不依賴struts和spring mvc等框架。乾淨簡潔通用。上傳下載檔案只需一行程式碼即可搞定。現將程式碼貼上來,與大家共享,誰有好的想法,歡迎提議。
工具類:FileUtils.java
上傳檔案的方法又寫了兩個過載,用法一看便知,不再解釋。import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; public class FileUtils { private FileUtils() { } public static void download(HttpServletRequest request, HttpServletResponse response, String relativeFilePath) { try { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); String fileName = request.getSession().getServletContext() .getRealPath("/") + relativeFilePath; fileName = fileName.replace("\\", "/");//統一分隔符格式 File file = new File(fileName); //如果檔案不存在 if (file == null || !file.exists()) { String msg = "file not exists!"; System.out.println(msg); PrintWriter out = response.getWriter(); out.write(msg); out.flush(); out.close(); return; } String fileType = request.getSession().getServletContext() .getMimeType(fileName); if (fileType == null) { fileType = "application/octet-stream"; } response.setContentType(fileType); System.out.println("檔案型別是:" + fileType); String simpleName = fileName.substring(fileName.lastIndexOf("/")+1); String newFileName = new String(simpleName.getBytes(), "ISO8859-1"); response.setHeader("Content-disposition", "attachment;filename="+newFileName); BufferedInputStream bis = new BufferedInputStream( new FileInputStream(file)); BufferedOutputStream bos = new BufferedOutputStream( response.getOutputStream()); byte[] buffer = new byte[1024]; int length = 0; while ((length = bis.read(buffer)) != -1) { bos.write(buffer, 0, length); } if (bis != null) bis.close(); if (bos != null) bos.close(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 檔案上傳 * * @param request HttpServletRequest * @param relativeUploadPath 上傳檔案儲存的相對路徑,例如"upload/",注意,末尾的"/"不要丟了 * @param maxSize 上傳的最大檔案尺寸,單位位元組 * @param thresholdSize 最大快取,單位位元組 * @param fileTypes 檔案型別,會根據上傳檔案的字尾名判斷。<br> * 比如支援上傳jpg,jpeg,gif,png圖片,那麼此處寫成".jpg .jpeg .gif .png",<br> * 也可以寫成".jpg/.jpeg/.gif/.png",型別之間的分隔符是什麼都可以,甚至可以不要,<br> * 直接寫成".jpg.jpeg.gif.png",但是型別前邊的"."不能丟 * @return */ public static List<String> upload(HttpServletRequest request, String relativeUploadPath, int maxSize, int thresholdSize, String fileTypes) { // 設定字元編碼 try { request.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } String tempPath = relativeUploadPath + "temp"; // 臨時檔案目錄 String serverPath = request.getSession().getServletContext().getRealPath("/").replace("\\", "/"); fileTypes = fileTypes.toLowerCase(); // 將字尾全轉換為小寫 //如果上傳檔案目錄和臨時目錄不存在則自動建立 if (!new File(serverPath + relativeUploadPath).isDirectory()) { new File(serverPath + relativeUploadPath).mkdirs(); } if (!new File(serverPath + tempPath).isDirectory()) { new File(serverPath + tempPath).mkdirs(); } DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(thresholdSize); // 最大快取 factory.setRepository(new File(serverPath + tempPath));// 臨時檔案目錄 ServletFileUpload upload = new ServletFileUpload(factory); upload.setSizeMax(maxSize);// 檔案最大上限 List<String> filePaths = new ArrayList<String>(); List<FileItem> items; try { items = upload.parseRequest(request); // 獲取所有檔案列表 for (FileItem item : items) { // 獲得檔名,檔名包括路徑 if (!item.isFormField()) { // 如果是檔案 // 檔名 String fileName = item.getName().replace("\\", "/"); //檔案字尾名 String suffix = null; if (fileName.lastIndexOf(".") > -1) { suffix = fileName.substring(fileName.lastIndexOf(".")); } else { //如果檔案沒有後綴名,不處理,直接跳過本次迴圈 continue; } // 不包含路徑的檔名 String SimpleFileName = fileName; if (fileName.indexOf("/") > -1) { SimpleFileName = fileName.substring(fileName .lastIndexOf("/") + 1); } // 如果檔案型別字串中包含該字尾名,儲存該檔案 if (fileTypes.indexOf(suffix.toLowerCase()) > -1) { String uuid = UUID.randomUUID().toString(); SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); String absoluteFilePath = serverPath + relativeUploadPath + sf.format(new Date()) + " " + uuid + " " + SimpleFileName; item.write(new File(absoluteFilePath)); filePaths.add(absoluteFilePath); } } } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } return filePaths; } /** * 檔案上傳 * * @param request HttpServletRequest * @param relativeUploadPath 上傳檔案儲存的相對路徑,例如"upload/",注意,末尾的"/"不要丟了 * @param maxSize 上傳的最大檔案尺寸,單位位元組 * @param fileTypes 檔案型別,會根據上傳檔案的字尾名判斷。<br> * 比如支援上傳jpg,jpeg,gif,png圖片,那麼此處寫成".jpg .jpeg .gif .png",<br> * 也可以寫成".jpg/.jpeg/.gif/.png",型別之間的分隔符是什麼都可以,甚至可以不要,<br> * 直接寫成".jpg.jpeg.gif.png",但是型別前邊的"."不能丟 * @return */ public static List<String> upload(HttpServletRequest request, String relativeUploadPath, int maxSize, String fileTypes) { return upload(request, relativeUploadPath, maxSize, 5*1024, fileTypes); } /** * 檔案上傳,不限大小 * * @param request HttpServletRequest * @param relativeUploadPath 上傳檔案儲存的相對路徑,例如"upload/",注意,末尾的"/"不要丟了 * @param fileTypes 檔案型別,會根據上傳檔案的字尾名判斷。<br> * 比如支援上傳jpg,jpeg,gif,png圖片,那麼此處寫成".jpg .jpeg .gif .png",<br> * 也可以寫成".jpg/.jpeg/.gif/.png",型別之間的分隔符是什麼都可以,甚至可以不要,<br> * 直接寫成".jpg.jpeg.gif.png",但是型別前邊的"."不能丟 * @return */ public static List<String> upload(HttpServletRequest request, String relativeUploadPath, String fileTypes) { return upload(request, relativeUploadPath, -1, 5*1024, fileTypes); } }
使用示例:FileUtilsTest.java
import java.io.IOException; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import common.utils.FileUtils; public class FileUtilsTest extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //下載檔案 FileUtils.download(request, response, "files/學生資訊.xls"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //上傳檔案 List<String> filePaths = FileUtils.upload(request, "upload/",".xls .xlsx"); System.out.println(filePaths); } }
不管是用struts還是spring mvc還是原生的servlet,拿到request,response都是輕而易舉吧,然後上傳下載就只需要上邊的一行程式碼了^_^
測試一下:
看看後臺列印結果:
上傳成功,再來測測下載:
也沒問題。
以後再需要上傳下載功能的時候,只需要匯入兩個jar包,把FileUtils類複製過去,然後FileUtils.download(),FileUtils.upload()就可以啦^_^
專案下載地址:http://download.csdn.net/detail/u013314786/9252777
考慮到專案版本問題,壓縮包中只包含了src和WebRoot兩個資料夾,要執行專案,只需在eclipse或者myeclipse中新建一個名為FileUtils的專案,然後把src裡的檔案複製到專案的src資料夾下,WebRoot裡的檔案複製到專案的WebRoot(myeclipse預設)或者WebContent(eclipse預設)資料夾下就可以執行啦。