天天看點

檔案上傳下載下傳 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" target="_blank" rel="external nofollow" >更多下載下傳資源</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();
}
           

繼續閱讀