input file文件上傳

一:瀏覽器post表單提交
通常的input組件表單提交時,按照form屬性提交的其中enctype=”application/x-www-form-urlencoded”是默認值

  <form action="RequestServlet" method="post" enctype="application/x-www-form-urlencoded">  

該提交方式只是提交普通表單;對於file組所選中的文件內容是不上傳的,因此需要設置:enctype屬性

enctype="multipart/form-data"

多部分提交方式,但注意編碼問題:對於post方式,瀏覽器會對中文進行編碼處理,發送字節,而普通組件的值得根據pageEncoding=”“的格式編碼。但是對於文件,是會檢測文件本身的編碼格式進行編碼。
因此在後臺我麼獲取的字節集,是根據pageEncoding=”“+文件本身的編碼格式混合的字節集,對於requset.setchar..設置編碼只能解析部分正確的編碼,其餘會亂碼
對於後臺接受的內容除了文件內容,是還有其他部分的識別碼:
前端提交

InputStream in=request.getInputStream();
        int len=-1;
        byte[] buf=new byte[1024];
        while((len=in.read(buf))!=-1){
            System.out.print(new String(buf,"utf-8"));
        }

數據格式
文件亂碼
可以看出:
除了組件值:流中具有序列碼,說明嗎等識別碼,並且對於不同編碼的文件以同一編碼流解析,會部分亂碼!
如果要在後臺接受文件,那麼我們必須去解析這些內容,確定有幾個文件,分別是什麼編碼,要拋棄掉識別碼,分別以什麼編碼寫相應文件對應的那段字節。這是十分複雜的。
然而有人幫我做好了解析工具,以便我們直接用就行了,我在這介紹一種:Apache的文件上傳工具
使用該工具解析步驟(只說明基礎版步驟):

public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //※下面這句解決上傳文件名的中文亂碼
        //注意,下面這句設置中文,如果是“multipart/form-data”表單,可以設置其中file組件的文件名,但對其中的普通表單組件無效。
        //注意,下面這句設置中文,如果是我們以前用的“application/x-www-form-urlencoded”表單,可以設置其中的普通表單組件。
        request.setCharacterEncoding("utf-8");

        //先獲取所接收文件我們要保存到哪裏的路徑
        String path = getServletContext().getRealPath("/imgs");

        //文件上傳需要臨時目錄(如果不指定,那麼該目錄就是tomcat/temp )
        File tempDir = new File("d:/a");
        DiskFileItemFactory fileFactory = new DiskFileItemFactory(1024*8, tempDir);//創建用於解析文件的工廠類,同時設置緩衝區的位置和大小
        //※※※※思路的入口
        ServletFileUpload upload = new ServletFileUpload(fileFactory);
        upload.setFileSizeMax(1024*1024*5);//設置每個文件最大爲5M
        upload.setSizeMax(1024*1024*8);//所有上傳文件大小之和的最大值,此處設最多能上傳8M

        //以下開始解析
        try {
            List<FileItem> list= upload.parseRequest(request);
            for(FileItem fi:list){
                if(fi.isFormField()){//普通表單組件,如:<input type="text" name="desc1"/>
                    String str = fi.getString("utf-8");//※以指定編碼的方式獲取,來解決普通表單組件的中文亂碼問題
                    System.out.println("普通表單組件..."+str);
                }else{//文件組件
                    String fileName = fi.getName();//文件名
                    System.out.println("fileName:"+fileName);
                    //由於上傳的文件“名字”可能會有中文,而服務器目錄當中的資源名稱不能夠用中文,因此要把它轉換成非中文的文件名(要考慮文件名不能重複)
                    String uuid = UUID.randomUUID().toString().replace("-", "");
                    String ext = fileName.substring( fileName.lastIndexOf("."));//截取文件的擴展名: .jpg
                    String newFileName = uuid+ext;
                    //真正的文件內容在 fi.getInputStream() 當中
                    FileUtils.copyInputStreamToFile(fi.getInputStream(), new File(path+"/"+newFileName));
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        }

    }

上面代碼我們要注意幾點:
1:request.setCharacterEncoding(“utf-8”);在enctype值不同的情況下能起到什麼作用
2:DiskFileItemFactory 與ServletFileUpload以及FileItem三個類的使用(需要網上下載相應jar包,導入項目中,jdk中無此類)
3:項目文件名不能有中文(原因:瀏覽器資源請求時會對中文編碼;如此,一個名爲:圖片.jpg 到達後臺會編碼成 字節名,服務器根據字節名查文件,又怎麼能查到文件呢?)
4:文件名的唯一性(資源名不能重複,服務器無法區分)
5:中文亂碼問題(代碼有處理)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章