1. 程式人生 > >使用form表單上傳檔案(一)

使用form表單上傳檔案(一)

今天在專案中要寫一個上傳檔案的功能,使用jsp中的form表單的形式完成。

首先新建一個jsp,使用最原始的form表單來完成。

jsp中的程式碼如下,很簡單:

<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>
因為是要上傳檔案,所以form表單中的enctype屬性必須是 multipart/form-data

因為是post請求,所以method屬性是post,, 

因為對應的servlet不在同一個專案中,故必須加上文根。

後臺servlet中直接獲取檔案的程式碼如下:

1.首先servlet中的init函式中

@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";
	}
使用init找到tomcat根目錄以及想要上傳到哪個資料夾下:

下面:

@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());   }

上傳附件的知識點寫的很亂,在這裡記錄一下,也為以後我自己複習找到能複習的地方。

不積跬步,無以至千里

不積小流,無以成江海