1. 程式人生 > 程式設計 >Springmvc模式上傳和下載與enctype對比

Springmvc模式上傳和下載與enctype對比

一般表單資料分為兩類

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

enctype帶檔案上傳的表單和不帶enctype的傳統表單,這兩種提交的資料有著不同的樣式,並且上傳檔案只能使用enctype。

@Override
  protected void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException {
    req.setCharacterEncoding("utf-8");
    resp.setContentType("text/html;charset=utf-8");
    //伺服器儲存檔案的地址,需自己定義
    String savepath = this.getServletContext().getRealPath("/upload");
    System.out.println(savepath);
    //如果檔案不存在,需要先進行判斷,並建立,否則會出現空檔案報錯
    File file=new File(savepath);
    if(!file.exists()){
      file.mkdir();
    }
    //工具類commons-fileupload包建立工廠物件
    DiskFileItemFactory itemFactory=new DiskFileItemFactory();
    ServletFileUpload  upload=new ServletFileUpload(itemFactory);
    //判斷是不是傳統表單
    if(!ServletFileUpload.isMultipartContent(req)){
      System.out.println("是傳統的表單 沒有上傳功能");
      return;
    }

    try {
      //表單的各項資料物件,封裝成集合
      List<FileItem> list = upload.parseRequest(req);
      for(FileItem item:list){

        //是普通的表單資料
        if(item.isFormField()){
          String fieldName = item.getFieldName();
          String value = item.getString("utf-8");
          System.out.println(fieldName+"  "+value);
        }else {
          String filename = item.getName();//上傳的檔名字
          if(filename==null||filename.trim().equals("")){
            // 當前上傳的檔案為空
            continue;
          }
          System.out.println(filename);
          //得到檔案的名字
          filename = filename.substring(filename.lastIndexOf("\\")+1);

          InputStream in = item.getInputStream();

          OutputStream out=new FileOutputStream(savepath+"\\"+filename);

          byte[] buf=new byte[1024];
          int len=0;
          while((len=in.read(buf))>0){
            out.write(buf,len);
          }
          in.close();
          out.close();
        }

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

  req.getRequestDispatcher("/downloadlist").forward(req,resp);
  }

上傳檔案的大致上,是將提交的檔案轉存到伺服器端的一個檔案目錄下。然後轉發到展示頁面供選擇。

下載檔案的一些設定

@Override
  protected void doPost(HttpServletRequest req,IOException {
    req.setCharacterEncoding("utf-8");
    resp.setContentType("text/html;charset=utf-8");
    //獲取前臺檔案所展示的檔名稱和儲存目錄下的名稱要一致,方便寫引數下載。
    String fileName= req.getParameter("file");

    //先獲取上傳目錄路徑
    String basePath = getServletContext().getRealPath("/upload");

    //如果檔名是中文,需要進行url編碼,此操作是為了避免不同瀏覽器的下載頁面下檔案亂碼的情況
    String agent = req.getHeader("User-Agent");
    String filenameEncoder = "";
    if (agent.contains("MSIE")) {
      // IE瀏覽器
      filenameEncoder = URLEncoder.encode(fileName,"utf-8");
      filenameEncoder = filenameEncoder.replace("+"," ");
    } else if (agent.contains("Firefox")) {
      // 火狐瀏覽器
      BASE64Encoder base64Encoder = new BASE64Encoder();
      filenameEncoder = "=?utf-8?B?"
          + base64Encoder.encode(fileName.getBytes("utf-8")) + "?=";
    } else {
      // 其它瀏覽器
      filenameEncoder = URLEncoder.encode(fileName,"utf-8");
    }


    //設定下載的響應頭
    resp.setHeader("content-disposition","attachment;fileName="+filenameEncoder);//此filenameEncoder必須經過轉碼處理
    //獲取一個檔案輸入流
    InputStream is = new FileInputStream(new File(basePath,fileName));
    //獲取response位元組流
    OutputStream out = resp.getOutputStream();
    byte[] b= new byte[1024];
    int len =-1;
    while((len=is.read(b))!=-1){
      out.write(b,len);
    }
    //關閉流
    out.close();
    is.close();
  }

下載的設定上需要注意檔名的一些亂碼問題,最主要的是區別於不同瀏覽器下的一些差異。需要對檔名轉碼處理。

還需要提前設定對瀏覽器的響應頭,告知瀏覽器是一個檔案。

resp.setHeader("content-disposition","attachment;fileName="+filenameEncoder);

接觸了springmvc模式後,對上面的上傳與下載進行優化,

此處上傳的功能依舊是採用表格上傳。檔案格式依舊是

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

後臺則是

@RequestMapping("/upload")
  public String upload(MultipartFile file,String userName,HttpServletRequest request) throws IOException {
    String filename = file.getOriginalFilename();

    String suffix = filename.substring(filename.lastIndexOf("."));

    if(suffix.equalsIgnoreCase(".jpg")){
      String uuid = UUID.randomUUID().toString();
      //FileUtils.copyInputStreamToFile(file.getInputStream(),new File("E://"+uuid+suffix));

      file.transferTo(new File("D://"+System.currentTimeMillis()+suffix));//位置儲存在硬碟上
//      file.transferTo(new File(request.getServletContext().getRealPath("/")+"static/userImages/"+file));
//      儲存在專案裡的目錄下
      request.setAttribute("result","上傳成功");
      return "/result.jsp";
    }else{
      request.setAttribute("result","上傳失敗");
      return "/result.jsp";
    }
  }

相比之前的傳統式上傳,springmvc模式下封裝了許多繁瑣的過程,通過transferTo即可實現一些相應的操作

而下載也是相應的簡化了許多

@RequestMapping("/download")
  public void download(String filename,HttpServletResponse response,HttpServletRequest request) throws IOException {
    response.setHeader("content-disposition","attachment;filename="+filename);

    ServletOutputStream outputStream = response.getOutputStream();

    String path = request.getServletContext().getRealPath("images");

    File file = new File(path,filename);

    byte[] bytes = FileUtils.readFileToByteArray(file);

    outputStream.write(bytes);

    outputStream.close();
  }

一般框架會省去許多重複性的工作,但底層的基本原理還是要清楚過程

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。