日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

初学Java Web(7)——文件的上传和下载

發(fā)布時間:2025/3/21 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 初学Java Web(7)——文件的上传和下载 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文件上傳

文件上傳前的準(zhǔn)備

  • 在表單中必須有一個上傳的控件
    <input type="file" name="testImg"/>
  • 因為 GET 方式有請求大小的限制,所以表單的提交方式必須是 POST
    <form action="/upload" method="post">
  • 表單默認(rèn)的編碼方式為?application/x-www-form-urlencoded?,應(yīng)該修改為?multipart/form-data?,以二進制的形式進行數(shù)據(jù)的傳輸
    <form action="/upload" method="post" enctype="multipart/form-data">
    • 注意:此時 Servlet 中就不能再使用?request對象.getParameter(String name)?來獲取請求參數(shù)

    上傳組件

    實現(xiàn)文件的上傳,需要基于以下兩種組件的一種:

    • Apache FileUpload 組件【操作比較復(fù)雜】
    • SmartUpload 組件【操作比較簡單,但存在一些問題】

    基于 FileUpload 組件

    使用基于Apache FileUpload上傳組件實現(xiàn)文件的上傳,步驟:

  • 將必要的 jar 包導(dǎo)入到項目中
    commons-fileupload-1.2.2.jar
    commons-io-1.4.jar
  • 簡單寫好 upload.jsp 上傳頁面:
  • <!DOCTYPE html> <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" import="java.util.*" %> <html> <head><title>文件的上傳和下載</title> </head> <body>文件上傳: <form action="/upload" method="post" enctype="multipart/form-data"><input type="file" name="testImg"/> <br><input type="submit"/> </form></body> </html>

  • 編寫 UploadServlet 處理相關(guān)請求:
  • package servlet;import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.List;@WebServlet("/upload") public class UploadServlet extends HttpServlet {protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 驗證請求是否滿足要求(post 請求 / enctype 是否以multipart打頭boolean isMultipart = ServletFileUpload.isMultipartContent(req);// 如果不滿足要求就立即結(jié)束對該請求的處理if (!isMultipart) {return;}try {// FileItem 是表單中的每一個元素的封裝// 創(chuàng)建一個 FileItem 的工廠類FileItemFactory factory = new DiskFileItemFactory();// 創(chuàng)建一個文件上傳處理器(裝飾設(shè)計模式)ServletFileUpload upload = new ServletFileUpload(factory);// 解析請求List<FileItem> items = upload.parseRequest(req);for (FileItem fileItem :items) {// 判斷空間是否是普通控件if (fileItem.isFormField()) {// 普通控件} else {// 上傳控件// 將上傳的文件保存到服務(wù)器fileItem.write(new File("C:/", "testImg.jpg"));}}} catch (Exception e) {e.printStackTrace();}} }

    文件上傳的細(xì)節(jié)

    上面已經(jīng)能實現(xiàn)簡單的文件上傳功能了,但文件上傳有很多需要注意的地方。

    • 緩存大小和臨時目錄
      在上傳文件的時候,如果文件過大,而且是將文件放在緩存中,就可能造成內(nèi)存溢出
      默認(rèn)的緩存大小為?10 kb,臨時目錄的默認(rèn)值為?tomcat/temp
    • 解決方案:將操作緩存大小的文件放在服務(wù)器的磁盤(臨時目錄)中,在文件的大小超過設(shè)定的緩存大小的時候就會使用到臨時目錄
    // 設(shè)置緩存大小 500kb factory.setSizeThreshold(1024*500); // 設(shè)置臨時目錄 factory.setRepository(new File("C:/"));
    • 通常不需要設(shè)置

    另一個問題是:如果用戶 A 上傳了一個文件名叫xxx,用戶 B 也上傳了一個文件名叫 xxx,那么此時用戶 B 的文件會把用戶 A 的文件給覆蓋掉。

    • 文件名稱的處理
      相同文件名稱的文件,后面的文件會把前面的文件覆蓋掉
    • 解決方案:使用UUID來生成一個隨機的而且不重復(fù)字符串作為文件的名稱,獲取真實文件的后綴名需要用到?FilenameUtils?這個工具類
    • 語法:
    String fileName = UUID.randomUUID().toString()+"."+FilenameUtils.getExtension(fileItem.getName());

    文件類型的約束

    上傳文件的類型應(yīng)該需要做一些約束的,比如在上傳頭像的時候就只允許上傳圖片,其他類型的文件都不應(yīng)該允許上傳,并且如果類型不正確的時候,應(yīng)該給用戶一個錯誤的提示。

    • jsp 文件增加顯示錯誤提示信息:
      我們給我們的 jsp 開頭增加一個?<span>?來顯示錯誤信息
    <!DOCTYPE html> <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8" import="java.util.*" %> <html> <head><title>文件的上傳和下載</title> </head> <body>文件上傳:<span>${errorMsg}</span> <form action="/upload" method="post" enctype="multipart/form-data"><input type="file" name="testImg"/> <br><input type="submit"/> </form></body> </html>
    • 判斷上傳文件類型:
      限制文件類型那么就需要對文件類型進行判斷
    • 語法:String contentType = fileItem.getContentType();
    • Servlet 源碼:
    package servlet;import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.io.FilenameUtils;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.List; import java.util.UUID;@WebServlet("/upload") public class UploadServlet extends HttpServlet {protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 驗證請求是否滿足要求(post 請求 / enctype 是否以multipart打頭boolean isMultipart = ServletFileUpload.isMultipartContent(req);// 如果不滿足要求就立即結(jié)束對該請求的處理if (!isMultipart) {return;}try {// FileItem 是表單中的每一個元素的封裝// 創(chuàng)建一個 FileItem 的工廠類FileItemFactory factory = new DiskFileItemFactory();// 創(chuàng)建一個文件上傳處理器(裝飾設(shè)計模式)ServletFileUpload upload = new ServletFileUpload(factory);// 解析請求List<FileItem> items = upload.parseRequest(req);for (FileItem fileItem :items) {// 判斷空間是否是普通控件if (fileItem.isFormField()) {// 普通控件} else {// 上傳控件String contentType = fileItem.getContentType();if (!contentType.startsWith("image/")) {// 實現(xiàn)簡單的錯誤提示req.setAttribute("errorMsg", "親,您上傳的文件格式不正確,請重新上傳!");req.getRequestDispatcher("upload.jsp").forward(req, resp);return; // 如果不是圖片類型則不再對請求進行處理}// 隨機命名文件名String fileName = UUID.randomUUID().toString() + "." + FilenameUtils.getExtension(fileItem.getName());// 將上傳的文件保存到服務(wù)器fileItem.write(new File("C:/", fileName));}}} catch (Exception e) {e.printStackTrace();}} }

    解決中文亂碼問題

    • 解決中文文件名亂碼(事實上我在本地測試并沒有出現(xiàn)亂碼),得到解析器以后,就直接設(shè)置解析器的編碼為UTF-8就行了
    fileUpload.setHeaderEncoding("UTF-8");
    • 解決表單數(shù)據(jù)亂碼,在獲取表單值的時候,按照UTF-8編碼來獲取
    String value = fileItem.getString("UTF-8");

    文件大小約束

    • 單個文件數(shù)據(jù)的大小約束
      即整個表單之中只有一個上傳控件
    • 語法:upload.setFileSizeMax(1024 * 500); // 單個文件不能超過500 kb
    • 一次請求數(shù)據(jù)的大小約束
      限制整個請求之中的數(shù)據(jù)大小
    • 語法:upload.setSizeMax(1024 * 750); // 整個請求文件大小不能超過 750 kb

    使用 Map 封裝請求信息

    上面提到,我們已經(jīng)無法用 request對象正常獲取到參數(shù),那么我們究竟應(yīng)該怎么辦呢?

    • 使用 Map 封裝一下就好了,等到要用的時候再從 Map 中取出

    SmartUpload

    上面已經(jīng)基于 FileUpload 實現(xiàn)了文件的上傳,事實上也沒有想象中那么復(fù)雜,讓我們來看看 SmartUpload

    要使用SmartUpload組件,就需要導(dǎo)入smartupload.jar開發(fā)包

    快速入門

    //實例化組件 SmartUpload smartUpload = new SmartUpload();//初始化上傳操作 smartUpload.initialize(this.getServletConfig(), request, response);try {//上傳準(zhǔn)備smartUpload.upload();//對于普通數(shù)據(jù),單純到request對象是無法獲取得到提交參數(shù)的。也是需要依賴smartUploadString password = smartUpload.getRequest().getParameter("password");System.out.println(password);//上傳到uploadFile文件夾中smartUpload.save("uploadFile");} catch (SmartUploadException e) {e.printStackTrace(); }
    • 摘自:這里
    • 上面鏈接提到 SmartUpload 組件在解決中文亂碼中有一些小問題,我沒有測試過,但我覺得自己寫一個 FileUpload 工具類已經(jīng)足夠使用了

    文件下載

  • 寫一個簡單的 jsp 頁面:
  • 在 WEB-INF 下創(chuàng)建 download 文件夾,里面放入一個 test.zip
  • 編寫 Servlet 處理相關(guān)請求
  • package servlet;import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.net.URLEncoder; import java.nio.file.Files; import java.nio.file.Paths;@WebServlet("/download") public class DownloadServlet extends HttpServlet {protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 設(shè)置響應(yīng)數(shù)據(jù)的 MIME 類型resp.setContentType("application/x-msdownload");// 獲取文件名稱String fileName = req.getParameter("fileName");// 判斷瀏覽器是否是 IEString userAgent = req.getHeader("User-Agent");if (userAgent.contains("MSIE")) {// IE// 設(shè)置文件的名稱resp.setHeader("Content-Disposition", "attachment; fileName="+ URLEncoder.encode(fileName, "UTF-8"));} else {// 非IEresp.setHeader("Content-Disposition", "attachment; fileName="+ new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));}// 獲取文件所在的路徑String path = req.getServletContext().getRealPath("/WEB-INF/download");// 獲取指定的文件對象File f = new File(path, fileName);ServletOutputStream out = resp.getOutputStream();// 將文件復(fù)制到輸出流中,響應(yīng)給瀏覽器Files.copy(Paths.get(f.getAbsolutePath()), out);} }

    歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處!
    簡書ID:@我沒有三顆心臟
    github:wmyskxz

    總結(jié)

    以上是生活随笔為你收集整理的初学Java Web(7)——文件的上传和下载的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产视频导航 | 欧美一级淫片免费视频魅影视频 | 亚洲色图20p | 一级片黑人 | 91av综合| 欧美一区二区免费电影 | 免费av福利| 亚洲av成人精品一区二区三区在线播放 | 风间由美av | 免费中文字幕日韩 | 热热色国产 | 午夜污片 | 欧洲精品久久 | 男女交性视频播放 | 男人的网站在线观看 | 免费av在线播放 | 青草福利| 一卡二卡在线 | 精品无码一区二区三区电影桃花 | 可以看av的网址 | 波多野结衣av片 | 国产视频一二三区 | 国产精品jizz在线观看老狼 | 丰满大肥婆肥奶大屁股 | 超碰成人网 | 在线中文av | 无码人妻精品一区二区三应用大全 | 欧美成人做爰猛烈床戏 | 久久久久久久久久福利 | 天天激情站 | 超黄网站在线观看 | 中文字幕av一区二区三区 | 亚洲综合自拍 | 亚洲欧美在线不卡 | www.啪啪.com| 刘亦菲久久免费一区二区 | 欧美性视频网站 | 嫩草av久久伊人妇女超级a | 名校风暴在线观看免费高清完整 | 国产一区二区三区四区五区六区 | 亚洲www久久久 | 国产乱国产乱老熟300部视频 | 久久黄色 | αv在线| 九九热视频精品在线观看 | 伊人一区二区三区四区 | 亚洲国产欧美一区二区三区深喉 | 老太婆av| 大香蕉视频一区二区 | 亚洲精品国产美女 | 日韩三级av在线 | 久久精品国产亚洲AV无码男同 | 成人福利网站在线观看 | 欧美国产日韩精品 | 精品国产1区 | 九九自拍偷拍 | 亚洲熟妇无码一区二区三区 | 国产一级二级三级 | 夜夜嗨国产 | 美女狠狠干 | 瑟瑟视频在线免费观看 | 99久久99久久精品免费看蜜桃 | 最新av中文字幕 | www.xxxxx日本 | 性生活视频在线播放 | 小俊大肉大捧一进一出好爽 | 91在线观看成人 | 日本在线免费观看 | 在线精品亚洲欧美日韩国产 | 亚洲性图一区二区三区 | 国产人妻人伦精品1国产 | 私拍在线 | 中文字幕精品一区二区精品 | 成人午夜免费观看 | 久久久无码精品亚洲国产 | 欧美激情18 | 色亚洲成人 | 国产精品毛片久久久 | 亚洲天堂免费 | 色屁屁www影院免费观看入口 | 影音先锋亚洲成aⅴ人在 | 天天操天天操天天操 | 色妻av | 色窝窝无码一区二区三区成人网站 | 成年人av| 久久手机视频 | 麻豆av一区二区三区在线观看 | 农村少妇无套内谢粗又长 | 在线观看免费黄网站 | 操亚洲| 成人免费播放 | 蜜桃香蕉视频 | aaaa免费视频 | 日本高清视频在线观看 | 好男人www日本 | 97人人插| www精品| 毛片久久久久 | 国产一区二区免费看 |