中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Servlet文件的上傳與下載怎么實現

發布時間:2022-06-18 13:38:01 來源:億速云 閱讀:113 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“Servlet文件的上傳與下載怎么實現”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Servlet文件的上傳與下載怎么實現”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

文件的上傳和下載

1. 文件上傳細節

要有一個 form 標簽,method-post請求 (因為get有長度限制)

form標簽的屬性 encType 值必須為 multipart/form-data

表示提交的數據以多端(每一個表單項一個數據段)的形式進行拼接,然后以二進制流的形式發送給服務器

在 form 標簽中使用 input type="file" 添加上傳的文件

編寫服務器代碼 (Servlet接收),接受處理上傳的數據

文件上傳http請求信息:

請求頭:Content-Type: multipart/form-data; boundary=------WebKitFormBoundaryCd3g75eOt35olUs7

解析:

  • Content-Type 表示提交的數據類型

  • multipart/form-data 表示以流的形式分段提交服務器

  • boundary 表示每段數據的分隔符,值:----WebKitFormBoundarylXiF4fEzpo9c8L4p 是瀏覽器每次隨機生成的,它就是每段數據的分界符。在每段里面 第一行是對表單項的描述,然后有個空行,下面是提交的值。

請求體:

------WebKitFormBoundaryCd3g75eOt35olUs7
Content-Disposition: form-data; name="username"

zhu
------WebKitFormBoundaryCd3g75eOt35olUs7
Content-Disposition: form-data; name="photo"; filename="head.jpg"
Content-Type: image/jpeg

文件的信息(很長這里省略了)
------WebKitFormBoundaryCd3g75eOt35olUs7--

因為客戶端是以按流的方式提交是,所以我們要按流的方式獲取,不能這樣: req.getParameter("username");

正確用法:

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("上傳成功");
    ServletInputStream inputStream = req.getInputStream(); // 先得到 字節輸入流
    byte[] buffer = new byte[1024]; // 緩沖區
    int readCount = 0;
    while ((readCount = inputStream.read(buffer)) != -1) { // 打印出來的就是上面全部的請求體
        System.out.println(new String(buffer, 0, readCount));
    }
}

2. 文件上傳

這種文件上傳(常用)有很多第三方提供好的API我們使用進行了,可以幫我們對收到的數據進行解析。

例如:commons-fileupload-1.2.1.jar (依賴于 commons-io-1.4.jar

  • 導入兩個jar包

  • 解析

關鍵的類:

  • ServletFileUpload 類:用于解析上傳的數據

  • FileItem 類:每一個表單項

//ServletFileUpload中的方法
// 判斷當前上傳的數據是否是多端的格式,不是解析不了
public boolean ServletFileUpload.isMultipartContent(HttpServletRequest req) 
// 解析上傳的數據,FileItem表示每一個表單項
public List<FileItem> parseRequest(HttpServletRequest req)
//FileItem中方法
// 判斷當前這個表單項是普通的表單項還是文件上傳的類型,true表示普通的
public boolean isFormField()    
// 獲取表單項name屬性值
public String getFieldName()
// 獲取當前表單項的值
public String getString() // 可傳入字符集,防止亂碼,一開始req.setCharacterEncoding("UTF-8");也行
// 獲取上傳的文件名
public String getName()
// 將上傳的文件寫道 參數file所指向的磁盤位置
public void write(File file)

Servlet上傳文件示例:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.setCharacterEncoding("UTF-8"); // 防止亂碼
    resp.setContentType("text/html; charset=utf-8");
    String savePath = getServletContext().getRealPath("/WEB-INF/uploadFile"); //保存的路徑
    // 首先判斷上傳的數據是否是多段的數據
    if (ServletFileUpload.isMultipartContent(req)) {
        FileItemFactory fileItemFactory = new DiskFileItemFactory(); // 創建FileItemFactory工廠的實現類,
        // 創建用于解析上傳數據的工具類
        ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); 
        try {
            List<FileItem> list = servletFileUpload.parseRequest(req); // 解析,得到每一個表單項
            for (FileItem fileItem : list) {
                if (fileItem.isFormField()) { // 普通表單項
                    System.out.print("表單項的name屬性值:" + fileItem.getFieldName());
                    System.out.println("  表單項的value:" + fileItem.getString("UTF-8"));
                } else { // 文件類型
                    System.out.print("文件的name屬性值:" + fileItem.getFieldName());
                    System.out.println("  上傳的文件名:" + fileItem.getName());
                    // 一般會保存到用戶訪問不能直接訪問的目錄下 File.separator是系統默認路徑分隔符,win下是 / 
                    // (下面這是保存到了部署的真是目錄下,保存到了服務器中)
                    // 可以用UUID保證文件名的唯一性,防止文件覆蓋。
                    // 防止單個目錄文件過多影響讀寫速度,還可以使用目錄生成算法分散儲存
                    fileItem.write(new File(savePath + File.separator + fileItem.getName()));
                    //fileItem.delete(); //關閉資源
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3. 文件下載

客戶端 ->(發送請求告訴服務器我要下載什么文件) -> 服務器

服務器干的內容:

  • 獲取要下載的文件名

  • 讀取要下載的文件內容

  • 通過響應頭告訴客戶端返回的數據類型是什么 (和要下載的類型一致)

  • 告訴的客戶端收到的數據是用于下載使用(還是用響應頭設置)

  • 把下載的的文件內容回傳給客戶端下載

這個也能用 commons-io-1.4.jar 的IOUtils 類:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    req.setCharacterEncoding("UTF-8"); // 防止亂碼
    resp.setCharacterEncoding("UTF-8");
    //1.獲取要下載的文件名路徑名,并通過ServletContext讀取讀取文件
    String downloadFileName = "head.jpg"; // 我們這里寫死了
    ServletContext servletContext = getServletContext();
    String savePath = servletContext.getRealPath("/WEB-INF/upload"); //以前上傳文件保存的目錄
    String downloadPath = savePath + File.separator + downloadFileName;
    //2.告訴客戶端返回的類型
    String downloadType = servletContext.getMimeType(downloadPath); //獲取要下載文件的類型 (這個是image/jpeg)
    resp.setContentType(downloadType); // (和要下載的類型一樣)
    //3.告訴客戶端收到的數據是用于下載的,不是直接顯示在頁面的
    // Content-Disposition表示收到的數據怎么處理,attachment表示附件下載使用,filename表示下載文件的名字
    // filename名可以不和本地的名字一樣,當有中文時會亂碼,因為http協議設置的的時候不支持中文,需要進行url編碼
    /resp.setHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
    resp.setHeader("Content-Disposition", 
                   "attachment;filename=" + URLEncoder.encode(downloadFileName, "UTF-8"));
    InputStream resourceAsStream = servletContext.getResourceAsStream(downloadPath); 
    // getResourceAsStream() 傳入文件路徑,讀取文件!!!!!!!!!!!!!
    // 4.commons-io-1.4.jar中有IOUtils我們可以直接用,不用自己read() write()了
    ServletOutputStream outputStream = resp.getOutputStream(); // 獲取響應的輸出流
    IOUtils.copy(resourceAsStream, outputStream); 
    // 讀取輸入流的信息復制給輸出流,輸出給客戶端,傳入一個輸入流和輸出流 (字節字符流都行)
}

讀到這里,這篇“Servlet文件的上傳與下載怎么實現”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

成安县| 交口县| 澜沧| 宁武县| 阿克苏市| 赞皇县| 中山市| 冕宁县| 芜湖市| 新巴尔虎右旗| 乐平市| 苗栗县| 舞阳县| 蒲城县| 罗田县| 元阳县| 彰化县| 子长县| 元朗区| 禄劝| 霍州市| 定襄县| 图片| 格尔木市| 达孜县| 饶平县| 苏尼特右旗| 武宁县| 桦甸市| 祥云县| 桐柏县| 通州市| 大名县| 达州市| 桦南县| 永登县| 彰化市| 新巴尔虎左旗| 澎湖县| 乌兰浩特市| 宽甸|