使用form表單上傳檔案(一)
今天在專案中要寫一個上傳檔案的功能,使用jsp中的form表單的形式完成。
首先新建一個jsp,使用最原始的form表單來完成。
jsp中的程式碼如下,很簡單:
因為是要上傳檔案,所以form表單中的enctype屬性必須是 multipart/form-data<form method="post" action="<%=ermDomainUrl %>/erm/fodderUpload.do" enctype="multipart/form-data"> 上傳: <input type="file" id="uploadInput" name="file"> <input type="text" name="schoolRI" value="<%=schoolRI%>"> <p>上傳圖片</p> <button type="submit">提交</button> </form>
因為是post請求,所以method屬性是post,,
因為對應的servlet不在同一個專案中,故必須加上文根。
後臺servlet中直接獲取檔案的程式碼如下:
1.首先servlet中的init函式中
使用init找到tomcat根目錄以及想要上傳到哪個資料夾下:@Override public void init() throws ServletException { //找到要存放的位置 String WEBINFPath = this.getServletContext().getRealPath("WEB-INF"); if(WEBINFPath==null){ String temp = ""; try { temp = this.getServletContext().getResource("/").getPath(); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } WEBINFPath = temp + File.separator + "WEB-INF"; } System.out.println(WEBINFPath); File webInfFile = new File(WEBINFPath); webRootPath = webInfFile.getParentFile().getParentFile().getParentFile().getAbsolutePath(); cachePath = webRootPath+File.separator+"ims_res"+File.separator+"caches"; }
下面:
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("大家好"); try { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); response.setContentType("text/html; charset=utf8"); PrintWriter out = response.getWriter(); //下面使用流的方式解析request物件 // InputStream stream = request.getInputStream(); // InputStreamReader isr = new InputStreamReader(stream); // BufferedReader br = new BufferedReader(isr); // String str = br.readLine(); // logger.info("str:"+str); //判斷提交過來的表單是否為上傳表單 boolean flag = ServletFileUpload.isMultipartContent(request); if(flag){ //構造一個檔案上傳處理物件 DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); //定義一個迭代器 Iterator items = null; //解析出表單中提交的檔案內容 items = upload.parseRequest(request).iterator(); //建立一個map用來接收引數 Map<String, String> mapParam = new HashMap<String, String>(); while(items.hasNext()){//判斷當前元素是否存在,並且指向下一個指標(即所謂的索引) FileItem item = (FileItem) items.next(); //判斷引數域是普通的表單輸入域還是檔案上傳域,如果是表單輸入域則返回true if(!item.isFormField()){ String fileName = item.getName(); if(!checkImage(fileName)){ throw new Exception("該圖片不是以.jpg或.png結尾的,請上傳以.jpg或.png結尾的圖片"); } File cacheFile = new File(cachePath); String fodderUploadPath = cachePath+File.separator+"fodderUpload"; if(cacheFile.exists()){ File fodderUploafFile = new File(fodderUploadPath); if(!fodderUploafFile.exists()){ FileUtil fu = new FileUtil(); fu.createDir(fodderUploadPath); } } //構建一個檔案上傳的路徑 //先把該圖片上傳到tomcat 的ims_res\caches\fodderUpload 目錄下 File uploadFile = new File(fodderUploadPath+"\\"+fileName); //返回檔案的大小,返回位元組數 Long fileLength = item.getSize(); //上傳檔案 item.write(uploadFile); out.println("檔名為fileName:"+fileName); out.println("檔案大小fileLength:"+fileLength); }else{ // String name = item.getFieldName(); // String value = item.getString(); // mapParam.put(name, value); // logger.info("name:"+name); // logger.info("value:"+value); } } } out.close(); } catch (Exception e) { e.printStackTrace(); } }
重寫doPost方法可以獲取上傳的檔案資訊。
獲取檔案的部分我就不再寫了。
這裡值得一提的是,我要在前臺往後臺servlet中傳引數的時候,即就是在form表單中:
<input type="text" name="schoolRI" value="<%=schoolRI%>">
後臺使用常規的辦法,可以使用 request.getParameter("schoolRI") 的方式獲取引數,但是在這裡不行,為什麼呢?
原因是這裡form表單中 enctype屬性的值為:multipart/form-data 這樣的話,後臺servlet 就不能使用 request.getParameter("schoolRI") 獲取引數了。
查了很多資料,這有一篇部落格寫的很好,引用一下,在這裡也要感謝一下這個作者。 http://blog.csdn.net/jpiverson/article/details/12042205
援引文章中的話:
FORM元素的enctype屬性指定了表單資料向伺服器提交時所採用的編碼型別,預設的預設值是“application/x-www-form-urlencoded”。
然而,在向伺服器傳送大量的文字、包含非ASCII字元的文字或二進位制資料時這種編碼方式效率很低。
在檔案上載時,所使用的編碼型別應當是“multipart/form-data”,它既可以傳送文字資料,也支援二進位制資料上載。
Browser端<form>表單的ENCTYPE屬性值為multipart/form-data,它告訴我們傳輸的資料要用到多媒體傳輸 協議,由於多媒體傳輸的都是大量的資料,所以規定上傳檔案必須是post方法,<input>的type屬性必須是file。
所以到最後 使用
在上述帶啊中: FileItem item = (FileItem) items.next();
使用item物件即可得到
for(FileItem i: items) { i.getFieldName(); //引數名 //i.getString(); //引數值(返回字串),如果是上傳檔案,則為檔案內容 //i.get(); //引數值(返回位元組陣列),如果是上傳檔案,則為檔案內容
//i.getSize(); //引數值的位元組大小 //i.getName(); //上傳檔案的檔名//i.getContentType(); //上傳檔案的內容型別 if(!i.isFormField()&&i.getSize()>0) //簡單引數返回true,檔案返回false Files.write(Paths.get("/upload/"+Paths.get(i.getName()).getFileName()), i.get()); }
上傳附件的知識點寫的很亂,在這裡記錄一下,也為以後我自己複習找到能複習的地方。
不積跬步,無以至千里
不積小流,無以成江海