<small id="7ktuj"></small>
      <bdo id="7ktuj"></bdo>
        <mark id="7ktuj"></mark>

        <source id="7ktuj"></source>
        <small id="7ktuj"></small>

        ITPub博客

        首頁 > 應用開發 > Java > javaWEB 之文件的上傳

        javaWEB 之文件的上傳

        原創 Java 作者:蝴蝶飛啊飛 時間:2019-10-15 13:42:47 0 刪除 編輯

        1.1 文件上傳三要素

        提供form 表單 ,method 必須是 post

        form 表單的 enctype 必須是 multipart/form-data

        提供 input type= file ” 類型輸入

        1.2 實現文件上傳

        1.2.1 項目準備

        導入 : commons-fileupload.jar

        commons-io.jar

        1.2.2 編寫上傳頁面

        <%@ page language="java" pageEncoding="UTF-8"%>

        <!DOCTYPE HTML>

        <html>

          <head>

            <title> 文件上傳 </title>

          </head>

          <body>

            <form action="${pageContext.request.contextPath}/servlet/UploadHandleServlet" enctype="multipart/form-data" method="post">

                 上傳用戶:<input type="text" name="username"><br/>

                 上傳文件1 <input type="file" name="file1"><br/>

                 上傳文件2 <input type="file" name="file2"><br/>

                <input type="submit" value=" 提交 ">

            </form>

          </body>

        </html>

        1.2.3 編寫處理代碼

        package me.gacl.web.controller;

        import java.io.File;

        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 UploadHandleServlet extends HttpServlet {

            public void doGet(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException {

                        // 得到上傳文件的保存目錄,將上傳的文件存放于 WEB-INF 目錄下,不允許外界直接訪問,保證上傳文件的安全

                        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");

                        File file = new File(savePath);

                        // 判斷上傳文件的保存目錄是否存在

                        if (!file.exists() && !file.isDirectory()) {

                            System.out.println(savePath+" 目錄不存在,需要創建 ");

                            // 創建目錄

                            file.mkdir();

                        }

                        // 消息提示

                        String message = "";

                        try{

                            // 使用 Apache 文件上傳組件處理文件上傳步驟:

                            //1 、創建一個 DiskFileItemFactory 工廠

                            DiskFileItemFactory factory = new DiskFileItemFactory();

                            //2 、創建一個文件上傳解析器

                            ServletFileUpload upload = new ServletFileUpload(factory);

                             // 解決上傳文件名的中文亂碼

                            upload.setHeaderEncoding("UTF-8");

                            //3 、判斷提交上來的數據是否是上傳表單的數據

                            if(!ServletFileUpload.isMultipartContent(request)){

                                // 按照傳統方式獲取數據

                                return;

                            }

                            //4 、使用 ServletFileUpload 解析器解析上傳數據,解析結果返回的是一個 List<FileItem> 集合,每一個 FileItem 對應一個 Form 表單的輸入項

                            List<FileItem> list = upload.parseRequest(request);

                            for(FileItem item : list){

                                // 如果 fileitem 中封裝的是普通輸入項的數據

                                if(item.isFormField()){

                                    String name = item.getFieldName();

                                    // 解決普通輸入項的數據的中文亂碼問題

                                    String value = item.getString("UTF-8");

                                    //value = new String(value.getBytes("iso8859-1"),"UTF-8");

                                    System.out.println(name + "=" + value);

                                }else{// 如果 fileitem 中封裝的是上傳文件

                                    // 得到上傳的文件名稱,

                                    String filename = item.getName();

                                    System.out.println(filename);

                                    if(filename==null || filename.trim().equals("")){

                                        continue;

                                    }

                                    // 注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如:   c:\a\b\1.txt ,而有些只是單純的文件名,如: 1.txt

                                    // 處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分

                                    filename = filename.substring(filename.lastIndexOf("\\")+1);

                                    // 獲取 item 中的上傳文件的輸入流

                                    InputStream in = item.getInputStream();

                                    // 創建一個文件輸出流

                                    FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);

                                    // 創建一個緩沖區

                                    byte buffer[] = new byte[1024];

                                    // 判斷輸入流中的數據是否已經讀完的標識

                                    int len = 0;

                                    // 循環將輸入流讀入到緩沖區當中, (len=in.read(buffer))>0 就表示 in 里面還有數據

                                    while((len=in.read(buffer))>0){

                                        // 使用 FileOutputStream 輸出流將緩沖區的數據寫入到指定的目錄 (savePath + "\\" + filename) 當中

                                        out.write(buffer, 0, len);

                                    }

                                    // 關閉輸入流

                                    in.close();

                                    // 關閉輸出流

                                    out.close();

                                    // 刪除處理文件上傳時生成的臨時文件

                                    item.delete();

                                    message = " 文件上傳成功! ";

                                }

                            }

                        }catch (Exception e) {

                            message= " 文件上傳失敗! ";

                            e.printStackTrace();   

                        }

                        request.setAttribute("message",message);

                        request.getRequestDispatcher("/message.jsp").forward(request, response);

            }

            public void doPost(HttpServletRequest request, HttpServletResponse response)

                    throws ServletException, IOException {

                doGet(request, response);

            }

        }

        1.2.4 配置

        <servlet>

            <servlet-name>UploadHandleServlet</servlet-name>

            <servlet-class>com.qf.web.UploadHandleServlet</servlet-class>

        </servlet>

        <servlet-mapping>

            <servlet-name>UploadHandleServlet</servlet-name>

            <url-pattern>/servlet/UploadHandleServlet</url-pattern>

        </servlet-mapping>

        1.3 文件上傳細節注意

        上述的代碼雖然可以成功將文件上傳到服務器上面的指定目錄當中,但是文件上傳功能有許多需要注意的小細節問題,以下列出的幾點需要特別注意的

        1 、為保證服務器安全,上傳文件應該放在外界無法直接訪問的目錄下,比如放于 WEB-INF 目錄下。

        2 、為防止文件覆蓋的現象發生,要為上傳外匯返傭http://www.kaifx.cn/文件產生一個唯一的文件名。

        3 、為防止一個目錄下面出現太多文件,要使用 hash 算法打散存儲。

        4 、要限制上傳文件的最大值。

        5 、要限制上傳文件的類型,在收到上傳文件名時,判斷后綴名是否合法。

        最終處理代碼改進為:

        public class UploadHandleServlet extends HttpServlet {

        public void doGet(HttpServletRequest request, HttpServletResponse response)

        throws ServletException, IOException {

        // 得到上傳文件的保存目錄,將上傳的文件存放于 WEB-INF 目錄下,不允許外界直接訪問,保證上傳文件的安全

        String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");

        // 上傳時生成的臨時文件保存目錄

        String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");

        File tmpFile = new File(tempPath);

        if (!tmpFile.exists()) {

        // 創建臨時目錄

        tmpFile.mkdir();

        }

        // 消息提示

        String message = “” ;

        try{

        // 使用 Apache 文件上傳組件處理文件上傳步驟:

        //1 、創建一個 DiskFileItemFactory 工廠

        DiskFileItemFactory factory = new DiskFileItemFactory();

        // 設置工廠的緩沖區的大小,當上傳的文件大小超過緩沖區的大小時,就會生成一個臨時文件存放到指定的臨時目錄當中。

        factory.setSizeThreshold(1024100);// 設置緩沖區的大小為 100KB ,如果不指定,那么緩沖區的大小默認是 10KB

        // 設置上傳時生成的臨時文件的保存目錄

        factory.setRepository(tmpFile);

        //2 、創建一個文件上傳解析器

        ServletFileUpload upload = new ServletFileUpload(factory);

        // 解決上傳文件名的中文亂碼

        upload.setHeaderEncoding( UTF-8 );

        //3 、判斷提交上來的數據是否是上傳表單的數據

        if(!ServletFileUpload.isMultipartContent(request)){

        // 按照傳統方式獲取數據

        return;

        }

        // 設置上傳單個文件的大小的最大值,目前是設置為 10241024 字節,也就是 1MB

        upload.setFileSizeMax(10241024);

        // 設置上傳文件總量的最大值,最大值 = 同時上傳的多個文件的大小的最大值的和,目前設置為 10MB

        upload.setSizeMax(10241024*10);

        //4 、使用 ServletFileUpload 解析器解析上傳數據,解析結果返回的是一個 List 集合,每一個 FileItem 對應一個 Form 表單的輸入項

        List list = upload.parseRequest(request);

        for(FileItem item : list){

        // 如果 fileitem 中封裝的是普通輸入項的數據

        if(item.isFormField()){

        String name = item.getFieldName();

        // 解決普通輸入項的數據的中文亂碼問題

        String value = item.getString( UTF-8 );

        //value = new String(value.getBytes( iso8859-1 ), UTF-8 );

        System.out.println(name + = + value);

        }else{// 如果 fileitem 中封裝的是上傳文件

        // 得到上傳的文件名稱,

        String filename = item.getName();

        System.out.println(filename);

        if(filename==null || filename.trim().equals("")){

        continue;

        }

        // 注意:不同的瀏覽器提交的文件名是不一樣的,有些瀏覽器提交上來的文件名是帶有路徑的,如: c:\a\b\1.txt ,而有些只是單純的文件名,如: 1.txt

        // 處理獲取到的上傳文件的文件名的路徑部分,只保留文件名部分

        filename = filename.substring(filename.lastIndexOf("\")+1);

        // 得到上傳文件的擴展名

        String fileExtName = filename.substring(filename.lastIndexOf(".")+1);

        // 如果需要限制上傳的文件類型,那么可以通過文件的擴展名來判斷上傳的文件類型是否合法

        System.out.println( “上傳的文件的擴展名是:” +fileExtName);

        // 獲取 item 中的上傳文件的輸入流

        InputStream in = item.getInputStream();

        // 得到文件保存的名稱

        String saveFilename = FileUploadUtils.makeFileName(filename);

        // 得到文件的保存目錄

        String realSavePath = FileUploadUtils.makePath(saveFilename, savePath);

        // 創建一個文件輸出流

        FileOutputStream out = new FileOutputStream(realSavePath + \ + saveFilename);

        // 創建一個緩沖區

        byte buffer[] = new byte[1024];

        // 判斷輸入流中的數據是否已經讀完的標識

        int len = 0;

        // 循環將輸入流讀入到緩沖區當中, (len=in.read(buffer))>0 就表示 in 里面還有數據

        while((len=in.read(buffer))>0){

        // 使用 FileOutputStream 輸出流將緩沖區的數據寫入到指定的目錄 (savePath + \ + filename) 當中

        out.write(buffer, 0, len);

        }

        // 關閉輸入流

        in.close();

        // 關閉輸出流

        out.close();

        // 刪除處理文件上傳時生成的臨時文件

        //item.delete();

        message = “文件上傳成功!” ;

        }

        }

        }catch (FileUploadBase.FileSizeLimitExceededException e) {

        e.printStackTrace();

        request.setAttribute( message , “單個文件超出最大值!!!” );

        request.getRequestDispatcher("/message.jsp").forward(request, response);

        return;

        }catch (FileUploadBase.SizeLimitExceededException e) {

        e.printStackTrace();

        request.setAttribute( message , “上傳文件的總的大小超出限制的最大值!!!” );

        request.getRequestDispatcher("/message.jsp").forward(request, response);

        return;

        }catch (Exception e) {

        message= “文件上傳失敗!” ;

        e.printStackTrace();

        }

        request.setAttribute( message ,message);

        request.getRequestDispatcher("/message.jsp").forward(request, response);

        }

        public void doPost(HttpServletRequest request, HttpServletResponse response)

                throws ServletException, IOException {

            doGet(request, response);

        }

        }

        // 文件上傳工具類

        public class FileUploadUtils {

        /**

        * @Method: makeFileName

        * @Description: 生成上傳文件的文件名,文件名以: uuid+""+ 文件的原始名稱

        * @Anthor: 孤傲蒼狼

        * @param filename 文件的原始名稱

        * @return uuid+""+ 文件的原始名稱

        */

        private static String makeFileName(String filename){ //2.jpg

        // 為防止文件覆蓋的現象發生,要為上傳文件產生一個唯一的文件名

        return UUID.randomUUID().toString() + _ + filename;

        }

        /**

         * 為防止一個目錄下面出現太多文件,要使用 hash 算法打散存儲

        * @param filename 文件名,要根據文件名生成存儲目錄

        * @param savePath 文件存儲路徑

        * @return 新的存儲目錄

        */

        private static  String makePath(String filename,String savePath){

            // 得到文件名的 hashCode 的值,得到的就是 filename 這個字符串對象在內存中的地址

            int hashcode = filename.hashCode();

            int dir1 = hashcode&0xf;  //0--15

            int dir2 = (hashcode&0xf0)>>4;  //0-15

            // 構造新的保存目錄

            String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5

            //File 既可以代表文件也可以代表目錄

            File file = new File(dir);

            // 如果目錄不存在

            if(!file.exists()){

                // 創建目錄

                file.mkdirs();

            }

            return dir;

        }

        }

        1.4 Servlet3.1 支持的文件上傳

        package com.qf.servlet;

        import java.io.IOException;

        import java.util.Collection;

        import javax.servlet.ServletException;

        import javax.servlet.annotation.MultipartConfig;

        import javax.servlet.annotation.WebServlet;

        import javax.servlet.http.HttpServlet;

        import javax.servlet.http.HttpServletRequest;

        import javax.servlet.http.HttpServletResponse;

        import javax.servlet.http.Part;

        import org.apache.commons.io.IOUtils;

        import com.qf.utils.FileUploadUtils;

        /**

         * Servlet implementation class UploadFileServlet2

         */

        @WebServlet("/upLoadfile2")

        @MultipartConfig(fileSizeThreshold=1024*100,maxFileSize=1024*1024*2,maxRequestSize=1024*1024*20)

        public class UploadFileServlet2 extends HttpServlet {

        private static final long serialVersionUID = 1L;

            /**

             * @see HttpServlet#HttpServlet()

             */

            public UploadFileServlet2() {

                super();

                // TODO Auto-generated constructor stub

            }

        /**

         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

         */

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

         //1 亂碼

                request.setCharacterEncoding("utf-8");

                response.setContentType("text/html;charset=utf-8");

                String savepath=request.getServletContext().getRealPath("/WEB-INF/upload");

                File dir=new File(savepath);

                if(!dir.exists()){

                    dir.mkdirs();

                }

                //2 獲取多分部集合

                Collection<Part> parts = request.getParts();

                if(parts!=null){

                    System.out.println("parts 的個數 :"+parts.size());

                    for (Part part : parts) {

                        System.out.println(part.getClass().getName());

                        // 判斷是文件還是普通項

                        String filename=part.getSubmittedFileName();

                        System.out.println(filename+"-------------");

                        if(filename!=null){

                            // 文件

                            if(filename.trim().length()==0){

                                continue;

                            }

                            // 獲取真實的文件名:解決 IE 文件名的問題,兼容 chrome

                            String dis= part.getHeader("Content-Disposition");

                            String realfilename=dis.substring(dis.lastIndexOf("filename=")+10,dis.length()-1);

                            realfilename=realfilename.substring(realfilename.lastIndexOf("\\")+1);

                            List<String> list= Arrays.asList(".jpg",".png",".bmp");

                            String ext=realfilename.substring(realfilename.lastIndexOf("."));

                            if(!list.contains(ext)){

                                response.getWriter().write(" 您上傳的文件類型不支持 ");

                                continue;

                            }

                            // 生成帶 uuid 文件名

                            String uuidfilename=UpLoadUtils.createNewFileName(realfilename);

                            // 分散存儲

                            String newpath=UpLoadUtils.createNewPath(savepath, realfilename);

                            // 保存文件

                            part.write(newpath+"/"+uuidfilename);

                            response.getWriter().write(" 上傳成功 :"+realfilename);

                            part.delete();// 刪除緩存文件

                        }else{

                            // 普通項

                            String name=part.getName();

                            String value = request.getParameter(name);

                            System.out.println(name+"..."+value);

                        }

                    }

                }

            }

        /**

         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

         */

        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // TODO Auto-generated method stub

        doGet(request, response);

        }

        }

        來自 “ ITPUB博客 ” ,鏈接:http://www.ep4tq.com/69946279/viewspace-2660015/,如需轉載,請注明出處,否則將追究法律責任。

        請登錄后發表評論 登錄
        全部評論
        管他誰是誰非,做自己的主宰,我是這條街最亮的崽!

        注冊時間:2019-08-22

        • 博文量
          49
        • 訪問量
          21835
        妹子图每日分享