Java web開發——文件的(de)上(shàng)傳和(hé / huò)下載 - 新聞資訊 - 雲南小程序開發|雲南軟件開發|雲南網站建設-昆明融晨信息技術有限公司

159-8711-8523

雲南網建設/小程序開發/軟件開發

知識

不(bù)管是(shì)網站,軟件還是(shì)小程序,都要(yào / yāo)直接或間接能爲(wéi / wèi)您産生價值,我們在(zài)追求其視覺表現的(de)同時(shí),更側重于(yú)功能的(de)便捷,營銷的(de)便利,運營的(de)高效,讓網站成爲(wéi / wèi)營銷工具,讓軟件能切實提升企業内部管理水平和(hé / huò)效率。優秀的(de)程序爲(wéi / wèi)後期升級提供便捷的(de)支持!

您當前位置>首頁 » 新聞資訊 » 網站建設 >

Java web開發——文件的(de)上(shàng)傳和(hé / huò)下載

發表時(shí)間:2018-7-28

發布人(rén):融晨科技

浏覽次數:55

打個(gè)廣告,幫朋友賣點東西,東西超便宜的(de)喲【衣服鞋子(zǐ)等】,廠家直接出(chū)貨,絕對低于(yú)市場價!!! 一般都比市場價便宜3—7折【都是(shì)牌子(zǐ)貨】,如果您感興趣,可以(yǐ)掃描屏幕下方的(de)二維碼,感謝關注!!!

微信

一、文件上(shàng)傳

1、概述

實現web開發中的(de)文件上(shàng)傳功能,需完成如下二步操作:

  • 在(zài)web頁面中添加上(shàng)傳輸入項
  • 在(zài)servlet中讀取上(shàng)傳文件的(de)數據,并保存到(dào)本地(dì / de)硬盤中。

2、在(zài)web頁面中

在(zài)web頁面中通過<input type=“file”>标簽添加上(shàng)傳輸入項,設置文件上(shàng)傳輸入項時(shí)須注意:

1、必須要(yào / yāo)設置input輸入項的(de)name屬性,否則浏覽器将不(bù)會發送上(shàng)傳文件的(de)數據。

2、必須把form的(de)enctype屬值設爲(wéi / wèi)multipart/form-data.設置該值後,浏覽器在(zài)上(shàng)傳文件時(shí),将把文件數據附帶在(zài)http請求消息體中,并使用MIME協議對上(shàng)傳的(de)文件進行描述,以(yǐ)方便接收方對上(shàng)傳數據進行解析和(hé / huò)處理。

    <form action="${pageContext.request.contextPath }/servlet/UploadServlet3" enctype="multipart/form-data" method="post">
        上(shàng)傳用戶:<input type="text" name="username"><br/>
        上(shàng)傳文件1:<input type="file" name="file1"><br/>
        上(shàng)傳文件2:<input type="file" name="file2"><br/>
        
        <input type="submit" value="提交">
    </form>

注意:如果要(yào / yāo)動态添加上(shàng)傳輸入項可以(yǐ):

<html>
  <head>
    <title>My JSP 'upload2.jsp' starting page</title>
    
    <script type="text/javascript">
        function addinput(){
            var div = document.getElementById("file");
            
            var input = document.createElement("input");
            input.type="file";
            input.name="filename";
            
            var del = document.createElement("input");
            del.type="button";
            del.value="删除";
            del.onclick = function d(){
                this.parentNode.parentNode.removeChild(this.parentNode);
            }
            
            
            var innerdiv = document.createElement("div");
            
            
            innerdiv.appendChild(input);
            innerdiv.appendChild(del);
            
            div.appendChild(innerdiv);
        }
    </script>
    
  </head>
  
  <body>
    
    
    <form action="" enctype="mutlipart/form-data"></form>
    <table>
        <tr>
            <td>上(shàng)傳用戶:</td>
            <td><input type="text" name="username"></td>
        </tr>
        <tr>        
            <td>上(shàng)傳文件:</td>
            <td>
                <input type="button" value="添加上(shàng)傳文件" class="has" src="https://img-blog.csdn.net/20180728200740972?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzIyMTcyMTMz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70" /> 

3、在(zài)Servlet中

1.基本介紹

在(zài)Servlet中通過開源組件( Commons-fileupload )讀取文件上(shàng)傳數據,并保存到(dào)本地(dì / de)硬盤中。使用Commons-fileupload組件實現文件上(shàng)傳,需要(yào / yāo)導入該組件相應的(de)支撐jar包:

Commons-fileupload和(hé / huò)commons-io

注意:如果表單的(de)提交類型爲(wéi / wèi)multipart/form-data的(de)話,在(zài)servlet方就(jiù)不(bù)能采用傳統方式獲取表單數據

String username = request.getParameter("username");
System.out.println(username);

2.相關方法

1.DiskFileItemFactory

DiskFileItemFactory 是(shì)創建 FileItem 對象的(de)工廠,這(zhè)個(gè)工廠類常用方法:

方法介紹public void setSizeThreshold(int sizeThreshold) 設置内存緩沖區的(de)大(dà)小,默認值爲(wéi / wèi)10K。當上(shàng)傳文件大(dà)于(yú)緩沖區大(dà)小時(shí), fileupload組件将使用臨時(shí)文件緩存上(shàng)傳文件。public void setRepository(java.io.File repository) 指定臨時(shí)文件目錄,默認值爲(wéi / wèi)System.getProperty("java.io.tmpdir").public DiskFileItemFactory(int sizeThreshold, java.io.File repository) 構造函數

2.ServletFileUpload

負責處理上(shàng)傳的(de)文件數據,并将表單中每個(gè)輸入項封裝成一個(gè) FileItem 對象中。常用方法有:

方法介紹boolean isMultipartContent(HttpServletRequest request) 判斷上(shàng)傳表單是(shì)否爲(wéi / wèi)multipart/form-data類型List parseRequest(HttpServletRequest request)解析request對象,并把表單中的(de)每一個(gè)輸入項包裝成一個(gè)fileItem 對象,并返回一個(gè)保存了(le/liǎo)所有FileItem的(de)list集合。setFileSizeMax(long fileSizeMax) 設置上(shàng)傳文件的(de)最大(dà)值setSizeMax(long sizeMax) 設置上(shàng)傳文件總量的(de)最大(dà)值setHeaderEncoding(java.lang.String encoding) 設置編碼格式setProgressListener(ProgressListener pListener) 上(shàng)傳監聽器,可以(yǐ)知道(dào)文件上(shàng)傳進度

3.servlet實現

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
?
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
?
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
?
public class UploadServlet2 extends HttpServlet {
?
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try{

            //1.得到(dào)解析器工廠
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //設置緩存文件路徑(臨時(shí)文件)
            factory.setRepository(new File(this.getServletContext().getRealPath("/WEB-INF/temp"))); 

            //2.得到(dào)解析器
            ServletFileUpload upload = new ServletFileUpload(factory);      
?
            upload.setHeaderEncoding("UTF-8");  //解決上(shàng)傳文件名的(de)中文亂碼
            //3.判斷上(shàng)傳表單的(de)類型
            if(!upload.isMultipartContent(request)){
                //上(shàng)傳表單爲(wéi / wèi)普通表單,則按照傳統方式獲取數據即可
                return;
            }

            //爲(wéi / wèi)上(shàng)傳表單,則調用解析器解析上(shàng)傳數據
            List<FileItem> list = upload.parseRequest(request);  //FileItem

            //遍曆list,得到(dào)用于(yú)封裝第一個(gè)上(shàng)傳輸入項數據fileItem對象
            for(FileItem item : list){

                if(item.isFormField()){
                    //得到(dào)的(de)是(shì)普通輸入項
                    String name = item.getFieldName();  //得到(dào)輸入項的(de)名稱
                    String value = item.getString("UTF-8");//或者String value = item.getString();加下
                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");
                    System.out.println(name + "=" + value);
                }else{
                    //得到(dào)上(shàng)傳輸入項
                    String filename = item.getName();  //得到(dào)上(shàng)傳文件名  C:\Documents and Settings\ThinkPad\桌面\1.txt(有些浏覽器)||1.txt
                    if(filename==null || filename.trim().equals("")){//如果上(shàng)傳輸入框爲(wéi / wèi)空,跳出(chū)
                        continue;
                    }
                    filename = filename.substring(filename.lastIndexOf("\\")+1);
                    InputStream in = item.getInputStream();   //得到(dào)上(shàng)傳數據
                    int len = 0;
                    byte buffer[]= new byte[1024];


                    String savepath = this.getServletContext().getRealPath("/upload");
                    FileOutputStream out = new FileOutputStream(savepath + "\\" + filename);  //向upload目錄中寫入文件
                    while((len=in.read(buffer))>0){
                        out.write(buffer, 0, len);
                    }

                    in.close();
                    out.close();
                    item.delete();//删除臨時(shí)文件
                }
            }

        }catch (Exception e) {
            e.printStackTrace();
        }   

    }
?
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
?
        doGet(request, response);
    }
?
}

注意:

1.上(shàng)傳的(de)文件一般禁止别人(rén)訪問,故可以(yǐ)放在(zài)WEB-INF目錄下

//用于(yú)保存上(shàng)傳文件的(de)目錄應該禁止外界直接訪問
String savepath = this.getServletContext().getRealPath("/WEB-INF/upload");
System.out.println(savepath);

2.爲(wéi / wèi)了(le/liǎo)防止上(shàng)傳名稱相同的(de)文件,可以(yǐ)使用UUID

    String savepath = this.getServletContext().getRealPath("/upload");
    String saveFilename = makeFileName(filename);  //得到(dào)文件保存的(de)名稱
    FileOutputStream out = new FileOutputStream(savepath + "\\" + saveFilename);  //向upload目錄中寫入文件
         。。。。。。。。。。。。。。。
?
public String makeFileName(String filename){  //2.jpg
        return UUID.randomUUID().toString() + "_" + filename;
}

3.防止一個(gè)文件夾下的(de)文件太多(文件夾下文件過多,将導緻打開緩慢)

    String savepath = this.getServletContext().getRealPath("/upload");
    String realSavePath = makePath(filename, savePath);  //得到(dào)文件的(de)保存目錄
    FileOutputStream out = new FileOutputStream(realSavePath + "\\" + filename);
?
public String makePath(String filename,String savePath){//文件的(de)存放位置是(shì)根據文件名算出(chū)的(de),以(yǐ)後再下載的(de)時(shí)候可以(yǐ)根據計算結果來(lái)确定文件存放的(de)地(dì / de)址

    int hashcode = filename.hashCode();//拿到(dào)filename的(de)地(dì / de)址
    int dir1 = hashcode&0xf;  //0--15,拿到(dào)低四位當一級目錄
    int dir2 = (hashcode&0xf0)>>4;  //0-15,5到(dào)8位當二級目錄

    String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
    File file = new File(dir);
    if(!file.exists()){//如果這(zhè)個(gè)目錄不(bù)存在(zài),創建
        file.mkdirs();
    }
    return dir;
}

4.限制上(shàng)傳文件的(de)大(dà)小

            upload.setFileSizeMax(1024);//單個(gè)文件不(bù)能超過1k
            upload.setSizeMax(1024*10);//總共不(bù)能超過10k
            List<FileItem> list = upload.parseRequest(request);
            for(FileItem item : list){
?
?
}catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("message", "文件超出(chū)最大(dà)值!!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            return;
        }

5.監聽文件上(shàng)傳進度

//2.得到(dào)解析器
ServletFileUpload upload = new ServletFileUpload(factory);      
?
upload.setProgressListener(new ProgressListener(){
    public void update(long pBytesRead, long pContentLength, int arg2) {
    System.out.println("文件大(dà)小爲(wéi / wèi):" + pContentLength + ",當前已處理:" + pBytesRead);
    }
});
?
upload.setHeaderEncoding("UTF-8");  //解決上(shàng)傳文件名的(de)中文亂碼

二、文件下載

文件下載列表:

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>  
  <body>
?
    <c:forEach var="me" items="${map}">
        <c:url value="/servlet/DownLoadServlet" var="downurl">
            <c:param name="filename" value="${me.key}"></c:param>
        </c:url>
        ${me.value }  <a href="${downurl}">下載</a>  <br/>
    </c:forEach>
    
  </body>
</html>

查找所有文件:

//列出(chū)網站所有下載文件
public class ListFileServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String filepath = this.getServletContext().getRealPath("/WEB-INF/upload");
        Map map = new HashMap();
        listfile(new File(filepath),map);

        request.setAttribute("map", map);
        request.getRequestDispatcher("/listfile.jsp").forward(request, response);
    }

    public void listfile(File file,Map map){
        if(!file.isFile()){//如果不(bù)是(shì)文件,是(shì)文件夾
            File files[] = file.listFiles();
            for(File f : files){
                listfile(f,map);
            }
        }else{
            String realname = file.getName().substring(file.getName().indexOf("_")+1);  //9349249849-88343-8344_阿_凡_達.avi
            map.put(file.getName(), realname);//UUID,文件名
        }

    }


    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

通過傳過來(lái)的(de)參數(文件名的(de)UUID)來(lái)算出(chū)文件所在(zài)文件夾,并将其取出(chū)

public class DownLoadServlet extends HttpServlet {
?
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
?


        String filename = request.getParameter("filename");  //23239283-92489-阿凡達.avi
        filename = new String(filename.getBytes("iso8859-1"),"UTF-8");
        String path = makePath(filename,this.getServletContext().getRealPath("/WEB-INF/upload"));

        File file = new File(path + "\\" + filename);
        if(!file.exists()){
            request.setAttribute("message", "您要(yào / yāo)下載的(de)資源已被删除!!");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
            return;
        }

        String realname = filename.substring(filename.indexOf("_")+1);
        response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));

        FileInputStream in = new FileInputStream(path + "\\" + filename);
        OutputStream out = response.getOutputStream();
        byte buffer[] = new byte[1024];
        int len = 0;
        while((len=in.read(buffer))>0){
            out.write(buffer, 0, len);
        }
        in.close();
        out.close();
    }


    public String makePath(String filename,String savePath){

        int hashcode = filename.hashCode();
 

相關案例查看更多