一.組件准備
Servlet實現文件上傳,需要添加第三方提供的jar包
commons-fileupload-1.2.2-bin.zip
commons-io-2.3-bin.zip
在http://commons.apache.org/downloads/index.html找,然后放在如下目錄下
文件上傳的表單提交方式必須是POST方式,
編碼類型:enctype="multipart/form-data",默認是 application/x-www-form-urlencoded
文件上傳
具體步驟:
* 1)獲得磁盤文件條目工廠 DiskFileItemFactory 要導包
* 2) 利用 request 獲取 真實路徑 ,供臨時文件存儲,和 最終文件存儲 ,這兩個存儲位置可不同,也可相同
* 3)對 DiskFileItemFactory 對象設置一些 屬性
* 4)高水平的API文件上傳處理 ServletFileUpload upload = new ServletFileUpload(factory); 目的是調用 parseRequest(request)方法 獲得 FileItem 集合list (一次上傳多個文件,意思是多個input file)
* 5)在 FileItem 對象中 獲取信息, 遍歷, 判斷 表單提交過來的信息 是否是 普通文本信息 另做處理
* 6)
* 第一種. 用第三方 提供的 item.write( new File(path,filename) ); 直接寫到磁盤上
* 第二種. 手動處理
二.理論准備
base標簽只能放置在head標簽內,只有href和target,所有瀏覽器都支持head標簽,里面的title是唯一必須的。<base> 標簽為頁面上的所有鏈接規定默認地址或默認目標。通常情況下,瀏覽器會從當前文檔的 URL 中提取相應的元素來填寫相對 URL 中的空白。使用 <base> 標簽可以改變這一點。瀏覽器隨后將不再使用當前文檔的 URL,而使用指定的基本 URL 來解析所有的相對 URL。這其中包括 <a>、<img>、<link>、<form> 標簽中的 URL。
<html><head><base href="http://www.w3school.com.cn/i/" /><base target="_blank" /></head><body><img src="eg_smile.gif" /><br /><p>請注意,我們已經為圖像規定了一個相對地址。由於我們已經在 head 部分規定了一個基准 URL,瀏覽器將在如下地址尋找圖片:</p><p>"http://www.w3school.com.cn/i/eg_smile.gif"</p><br /><br /><p><a href="http://www.w3school.com.cn">W3School</a></p><p>請注意,鏈接會在新窗口中打開,即使鏈接中沒有 target="_blank" 屬性。這是因為 base 元素的 target 屬性已經被設置為 "_blank" 了。</p></body></html>
三.代碼實現
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%//得到項目的名字,如果項目為根目錄,則得到一個"",即空的字條串String path = request.getContextPath();//scheme:httpString basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><!--所有瀏覽器都支持head標簽,里面的title是唯一必須的。<base> 標簽為頁面上的所有鏈接規定默認地址或默認目標。通常情況下,瀏覽器會從當前文檔的 URL 中提取相應的元素來填寫相對 URL 中的空白。使用 <base> 標簽可以改變這一點。瀏覽器隨后將不再使用當前文檔的 URL,而使用指定的基本 URL 來解析所有的相對 URL。這其中包括 <a>、<img>、<link>、<form> 標簽中的 URL。--><base href="<%=basePath%>"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>文件上傳</title></head><body><form action="2.jsp" method="post" enctype="multipart/form-data"><label>文件:<input type="file" name="myFile"></label><br /> <label>其他信息:<input type="text" name="info" /></label><br /> <inputtype="submit" value="提交" /></form></body></html>
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><%@page import="org.apache.commons.fileupload.servlet.*" %><%@page import="org.apache.commons.fileupload.*" %><%@page import="org.apache.commons.fileupload.disk.*" %><%@page import="java.util.List" %><%@page import="java.util.Iterator" %><%@page import="java.io.*" %><%//Check that we have a file upload request//監測request中是否包含文件boolean isMultipart = ServletFileUpload.isMultipartContent(request);if(isMultipart){out.print("包含文件");}else{out.print("不包含文件");}out.print("<br/>");// Create a factory for disk-based file itemsFileItemFactory factory = new DiskFileItemFactory();//獲取文件需要上傳到的路徑// String path = request.getRealPath("/upload");String path = session.getServletContext().getRealPath("upload");//如果沒以下兩行設置的話,上傳大的 文件 會占用 很多內存,//設置暫時存放的 存儲室 , 這個存儲室,可以和 最終存儲文件 的目錄不同/*** 原理 它是先存到 暫時存儲室,然后在真正寫到 對應目錄的硬盤上,* 按理來說 當上傳一個文件時,其實是上傳了兩份,第一個是以 .tem 格式的* 然后再將其真正寫到 對應目錄的硬盤上*/// factory.setRepository(new File(path));//設置 緩存的大小,當上傳文件的容量超過該緩存時,直接放到 暫時存儲室// factory.setSizeThreshold(1024*1024) ;// Create a new file upload handlerServletFileUpload upload = new ServletFileUpload(factory);// Parse the requestList items = upload.parseRequest(request);// Process the uploaded itemsIterator iter = items.iterator();while (iter.hasNext()) {FileItem item = (FileItem) iter.next();if (item.isFormField()) {//如果是普通表單控件////獲取表單的屬性名字String name = item.getFieldName();//獲取用戶具體輸入的字符串 ,名字起得挺好,因為表單提交過來的是 字符串類型的String value = item.getString();request.setAttribute(name,value);out.print("name:"+name +"<br/>");out.print("value:"+value +"<br/>");} else {//如果是文件//也叫name是為了和上面保持一致,方便顯示頁面String name = item.getFieldName();String fileName = item.getName();String contentType = item.getContentType();boolean isInMemory = item.isInMemory();long sizeInBytes = item.getSize();out.print("表單文件控件名:"+name +"<br/>");//絕對路徑的out.print("上傳文件名:"+fileName +"<br/>");out.print("文件類型:"+contentType +"<br/>");out.print("是否保存在內存中:"+isInMemory +"<br/>");out.print("大小:"+sizeInBytes +"字節<br/>");//上傳文件//獲取文件名String f_name = fileName.substring(fileName.lastIndexOf("\\")+1,fileName.length());request.setAttribute(name,f_name);// 進行文件上傳File uploadedFile = new File(path ,f_name);item.write(uploadedFile);/* OutputStream out = new FileOutputStream(new File(path,filename));InputStream in = item.getInputStream() ;int length = 0 ;byte [] buf = new byte[1024] ;System.out.println("獲取上傳文件的總共的容量:"+item.getSize());// in.read(buf) 每次讀到的數據存放在 buf 數組中while( (length = in.read(buf) ) != -1){//在 buf 數組中 取出數據 寫到 (輸出流)磁盤上out.write(buf, 0, length);}in.close();*/}}request.getRequestDispatcher("showFile.jsp").forward(request, response);%>
如果有不足或者錯誤的地方,還請指出,不勝感激,願你我共同進步。。。。<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"><title>文件展示</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"><meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">--></head><body>用戶名:${requestScope.usename } <br/>文件:${requestScope.myfile }<br/><!-- 把上傳的圖片顯示出來 --><img alt="go" src="upload/<%=(String)request.getAttribute("myfile")%> " /></body></html>

