上傳
基本實作思路
- 表單設計
enctype="multipart/form-data"
- 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(); } }
- 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);
下載下傳
總結起來就是兩頭一流:
兩頭:
- Content-Type :用來設定檔案的類型,檔案類型可以通過this.getServletContext().getMimeType(String s)方法擷取到,參數是檔案名。
- 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();
檔案名的編碼問題
解決方案見上方