天天看點

JavaWeb實作上傳下載下傳

上傳

基本實作思路

  1. 表單設計
    enctype="multipart/form-data"
               
  2. Servlet設計
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         	//設定編碼
            request.setCharacterEncoding(StandardCharsets.UTF_8.toString());
            response.setContentType("text/html;charset=utf-8");
         	//擷取解析器工廠,其中的兩個參數分别為記憶體的緩存大小和緩存的臨時存放路徑
            DiskFileItemFactory dif=new DiskFileItemFactory(1024*20,new File("C:/temp"));
            //擷取解析器
         	ServletFileUpload sfi=new ServletFileUpload(dif);
            try {
                //通過解析器擷取List,List中存放的是FileItem
                List<FileItem> items = sfi.parseRequest(request);
                for (FileItem item : items) {
                    //該方法用來判斷是否為普通表單
                    if (item.isFormField()){
                        System.out.println(item.getFieldName()+" "+item.getString(StandardCharsets.UTF_8.toString()));
                    }else{
                        //因為個别浏覽器的檔案名會包含磁盤路徑,是以需要先通過判斷來截取實際檔案名
                        String name=item.getName();
                        int index=name.lastIndexOf("\\");
                        if (index!=-1){
                            name=name.substring(index+1);
                        }
                        //為了避免重名,是以為檔案重新命名
                        String saveName= CommonsUtils.getUUID()+"_"+name;
                        //擷取檔案名對象的hashcode
                        int hashCode = name.hashCode();
                        //擷取hashcode的16進制表示的字元串
                        String hexString = Integer.toHexString(hashCode);
                        //擷取web項目的實際路徑資訊
                        String root=this.getServletContext().getRealPath("/WEB-INF/files");
                        //設定儲存路徑:規則為截取字元串的第一個和第二個字元作為路徑
                        File file=new File(root,hexString.charAt(0)+"/"+hexString.charAt(1));
                        //該方法可以判斷路徑是否存在,若路徑存在啥也不幹,若不存在則建立路徑
                        file.mkdirs();
                        //檔案的儲存路徑
                        File saveFile=new File(file,saveName);
                        //儲存檔案
                        item.write(saveFile);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
               
  3. Servlet3.0對上傳的支援
    req.setCharacterEncoding("utf-8");
    //可以直接擷取參數
    System.out.println(req.getParameter("username"));
    //擷取Part對象,以便于對檔案的操作
    Part part = req.getPart("pic");
    String header = part.getHeader("Content-Disposition");
    int indexOf = header.lastIndexOf("filename=");
    int start=indexOf+10;
    int end=header.length()-1;
    String filename=header.substring(start,end);        					                //寫入檔案
    part.write("C:/Users/wu2we/Desktop/java/bookstore/out/artifacts/bookstore_war_exploded/book_img/"+filename);
               

下載下傳

總結起來就是兩頭一流:

兩頭:

  1. Content-Type :用來設定檔案的類型,檔案類型可以通過this.getServletContext().getMimeType(String s)方法擷取到,參數是檔案名。
  2. Content-Disposition:用來設定下載下傳方式(彈出下載下傳框),以及檔案名,格式固定:attachment;filename=?

一流:即輸出流

File file=new File("C:/Users/wu2we/Desktop/jdk-9_漢化版.CHM");
FileInputStream inputStream=new FileInputStream(file);
String mimeType = this.getServletContext().getMimeType("C:/Users/wu2we/Desktop/jdk-9_漢化版.CHM");
//解決編碼問題
String newDisposition= DownUtils.filenameEncoding("jdk-9_漢化版.CHM",request);
String disposition="attachment;filename="+newDisposition;
response.setHeader("Content-Type",mimeType);
response.setHeader("Content-Disposition",disposition);
ServletOutputStream stream = response.getOutputStream();
IOUtils.copy(inputStream,stream);
inputStream.close();
           

檔案名的編碼問題

解決方案見上方