Springmvc模式上傳和下載與enctype對比
阿新 • • 發佈:2020-12-07
一般表單資料分為兩類
<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(); }
一般框架會省去許多重複性的工作,但底層的基本原理還是要清楚過程
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。