1. 程式人生 > >檔案上傳下載 Upload&Download

檔案上傳下載 Upload&Download

檔案的上傳下載 Upload&Download

(一)檔案的上傳

  • 檔案的上傳即將本地檔案上傳到遠端伺服器端

  • 檔案上傳的流也需要放到一個表單中

2、檔案上傳的表單的要求

  1. 檔案上傳的表單需要設定的請求方式是POST請求
  2. 檔案上傳的表單項的type屬性需要指定為:file

    <input type="file" name="photo">
    
  3. 給form表單新增一個enctype屬性

    該屬性的預設值是:application/x-www-form-urlencoded
    當是該屬性值時表單中的內容會使用URL進行編碼
    我們上傳檔案需要將該屬性的值修改為:multipart/form-data
    使用該值時表單中的表單項會以一個多部件的形式提交到伺服器,
    一個表單項就是一個多部件,而且各個多部件之間使用像------WebKitFormBoundarypkeMFtY9i1D0COuu這樣的分隔符進行分割
    

3 Upload裝備三個核心類 七個核心方法

FileUpload是Apache為我們提供的專門用來進行檔案上傳和下載的工具類

使用FileUpload需要匯入以下jar包

    commons-fileupload-1.3.1.jar
    commons-io-2.5.jar

核心類:

<1>DiskFileItemFactory
建立工廠類例項

<2>ServletFileUpload
建立解析器類例項

<3>FileItem
通過解析器解析請求之後得到的沒個多部件就對應一個個FileItem物件

核心方法:

isFormField()
用來判斷表單項是否是一個普通表單項
getFieldName()
用來獲取表單項中的name屬性值
getString(String encoding)
用來獲取表單項中輸入的value屬性值,方法中傳入一個字符集
getContentType()
用來獲取檔案的型別,是一個MIME值
getName()
用來獲取檔名
getSize()
用來獲取檔案的大小,單位位元組
write(File file)
將檔案寫到某個地方

具體實現:

jsp頁面的實現如下:

<body>
<form action="${pageContext.request.contextPath}/uploadServlet" method="post" enctype="multipart/form-data">
  <center>
    <table height="250px">
         <tr>
            <td>使用者名稱:</td>
            <td><input type="text" name="userName"/></td>
         </tr>
         <tr>
            <td>檔案1:</td>
            <td><input type="file" name="file1"/></td>
         </tr>
         <tr>
            <td>檔案2:</td>
            <td><input type="file" name="file2"/></td>
         </tr>
         <tr>
            <td>檔案3:</td>
            <td><input type="file" name="file3"/></td>
         </tr>
         <tr>
            <td></td>
            <td><input type="submit" value="確定"/></td>
         </tr>
         <tr>
             <td>
             <a href="${pageContext.request.contextPath }/downLoadServlet">更多下載資源</a>
             </td>
         </tr>
          <tr>
            <td><span style="color: red">${requestScope.msg }</span></td>
          </tr>
          <tr>
            <td><span style="color: green">${requestScope.mesgsuccess }</span></td>
          </tr>
    </table>
    </center>
</form>
</body>

實現檔案上傳的Servlet如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    /*用此方式獲取不到表單提交引數正確的實現如下
    String username = request.getParameter("username");
    String file1 = request.getParameter("file1");
    String file2 = request.getParameter("file2");
    String file3 = request.getParameter("file3");
    System.out.println(username+file1+file2+file3);*/

    //1.建立工廠類例項
    DiskFileItemFactory factory=new DiskFileItemFactory();
    //2.建立解析器類例項
    ServletFileUpload fileUpload=new ServletFileUpload(factory);
    //設定單個檔案的大小不超過200KB
    fileUpload.setFileSizeMax(1024*400*10);
    //設定檔案的總大小不超過450KB
    fileUpload.setSizeMax(1024*400*30);
    //3.解析請求
    try {
        List<FileItem> parseRequest = fileUpload.parseRequest(request);
        for (FileItem fileItem : parseRequest) {

            /*核心方法:
             * isFormField():用來判斷表單項是否是一個普通表單項
             * getFieldName():用來獲取表單項中的name屬性值
             * getString(String encoding):用來獲取表單項中輸入的value屬性值,方法中傳入一個字符集
             * 
             * getContentType():用來獲取檔案的型別,是一個MIME值
             * getName():用來獲取檔名
             * getSize():用來獲取檔案的大小
             * write(File file):將檔案寫到硬碟上
             */

            if(fileItem.isFormField()) {
                //證明是一個普通表單項
                //獲取name屬性值
                String fieldName = fileItem.getFieldName();
                //獲取使用者輸入的值設定亂碼
                String inputValue = fileItem.getString("UTF-8");

                System.out.println("表單項的name屬性值為:"+fieldName);
                System.out.println("表單項中使用者輸入的值是 :"+inputValue);
            }else {
                //證明提交型別為檔案 獲取檔案的型別
                String contentType = fileItem.getContentType();
                //獲取檔名
                String name = fileItem.getName();
                //擷取檔名 不要前面的路徑(因為ie瀏覽器會帶路徑)
                if(name.contains("\\")) {
                    name=name.substring(name.lastIndexOf("\\")+1);
                }
                //獲取單個檔案的大小
                long fileSize = fileItem.getSize();

                System.out.println("檔案的型別是:"+contentType);
                System.out.println("檔名是:"+name);
                System.out.println("檔案的大小是:"+fileSize+"位元組");

                //獲取伺服器端upload目錄的真實路徑(將檔案上傳到伺服器)
                ServletContext servletContext = this.getServletContext();
                String realPath = servletContext.getRealPath("/upload");

                //建立目錄
                File file=new File(realPath);
                if(!file.exists()){
                    //建立這個目錄
                    file.mkdirs();
                }
                //使用UUID生成一個全球唯一的字串
                String uuid = UUID.randomUUID().toString().replace("-","");
                //將上傳的檔案寫到伺服器端的upload目錄中
               fileItem.write(new File(realPath+"/"+uuid+"_"+name));
            }

        }
    } catch (FileSizeLimitExceededException e) {
//e.printStackTrace();
        //設定一個錯誤訊息
        request.setAttribute("msg", "單個檔案不要超過4MB!");
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    } catch (SizeLimitExceededException e) {
//  e.printStackTrace();
        //設定一個錯誤訊息
        request.setAttribute("msg", "總檔案大小不要超過12MB!");
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    } catch (Exception e) {
        e.printStackTrace();
    }
    request.setAttribute("mesgsuccess", "上傳檔案成功!!");
    request.getRequestDispatcher("/index.jsp").forward(request, response);
   }

(二)檔案的下載

檔案的下載即將檔案從伺服器端下載到本地

檔案的下載只需要將檔案的地址作為一個超連結顯示在瀏覽器端,然後點選超連結即可完成下載
但是這樣做對於支援該檔案格式的瀏覽器來說並不會下載該檔案,而是直接將這個檔案開啟;

而且我們也不可以給檔案設定下載的許可權,所以我們通常將被下載的檔案放到WEB-INF下,通過

Servlet來下載檔案

1.通過在Servlet下載檔案

1)建立一個輸入流
2)設定兩個響應頭
3)使用輸出流輸出到瀏覽器端

2.具體實現:

Servlet實現如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //獲取檔案在伺服器端的真實路徑
            ServletContext servletContext = this.getServletContext();

            String realPath = servletContext.getRealPath("/WEB-INF/download/相見恨晚.mp3");

            //1.建立一個輸入流
            InputStream is = new FileInputStream(realPath);


            String fileName = "相見恨晚.mp3";

            //獲取使用者使用的瀏覽器
            String header = request.getHeader("User-Agent");
            if(header.contains("Firefox")){
                //證明使用的是火狐瀏覽器
                //對應火狐瀏覽器,我們需要進行BASE64編碼
                fileName = "=?utf-8?b?"+new BASE64Encoder().encode(fileName.getBytes())+"?=";
            }else{
                //對檔名進行URL編碼
                fileName = URLEncoder.encode(fileName, "UTF-8");
            }
            //2.設定兩個響應頭
            //①設定檔案的型別,是一個MIME值
            //獲取檔案的MIME值
            String mimeType = servletContext.getMimeType(realPath);
            System.out.println(mimeType);

            response.setHeader("Content-Type", mimeType);
            //②設定瀏覽器怎樣處理當前檔案
            response.setHeader("Content-Disposition", "attachment; filename="+fileName);
            //3.使用輸出流將檔案輸出到瀏覽器
            ServletOutputStream os = response.getOutputStream();
            //將輸入流複製到輸出流中
            IOUtils.copy(is, os);
            //關閉流
            is.close();
}