13上傳 下載

**文件上傳的概述**
	
	1.瞭解什麼是文件上傳
	2.文件上傳須要你們記住編寫客戶端須要有3個注意事項。
	3.什麼是文件上傳
		* 把本地的文件保存到服務器端
	
	4.作文件上傳,該怎麼作?
		* 客戶端
			* 選擇一個要上傳的文件
			* 須要提供文件的選擇輸入框(<input type="file">)
			* 注意:若是完成文件的上傳,必須有3點注意事項的
				* 編寫表單,method="post" 必須是post
				* 表單中還有一個屬性,enctype="multipart/form-data"
				* 編寫文件的選項框	<input type="file" name="必需要指定,名稱能夠任意">
		
		* 服務器端
			* 把上傳的文件寫入到某個指定的文件夾下

![](./圖片/01-文件上傳的概述.bmp)	
	
----------
	
**Fileupload文件上傳的組件**
	
	1.由apache提供的開源的jar包
		* 導入開發的jar包
			* commons-fileupload-1.2.1.jar
			* commons-io-1.4.jar
	
	2.入門的開發
		* 開發的步驟,開發的步驟比較固定
	
![](./圖片/02-FileUpload開發的流程.bmp)	
	
----------
	
**文件上傳入門案例**
	
	1.編寫入門的案例,目的:讓你們來熟悉開發的步驟,使用一些對象和方法,後面講解。
	2.文件上傳的案例步驟
		* 客戶端
			* 注意3個注意事項		
		
		* 服務器端
			* 採用的是FileUpload文件上傳的組件,不要忘記導入開發的jar包。
			* 建立工廠類,生成對象
			* 建立核心解析類,解析request請求,獲取到文件項(FileItem)
			* 操做FileItem類的方法就能夠完成文件的上傳了
	
----------
	
### FileUpload組件的類和方法 ###
	
----------
	
**DiskFileItemFactory類**
	
	1.DiskFileItemFactory:表明磁盤文件項工廠類,做用:用來生產FileItem對象的。
	2.方法
		* DiskFileItemFactory()					-- 空的構造常常使用的。
		
		* DiskFileItemFactory(int sizeThreshold, java.io.File repository)	
			* sizeThreshold		-- 設置上傳文件的緩衝區的大小,若是不指定,有默認值是10K
			* repository		-- 設置臨時文件的存儲目錄,若是上傳的文件,超過了緩衝區的大小,產生臨時文件,設置臨時文件存儲的目錄。
		
		* void setSizeThreshold(int sizeThreshold)			-- 設置緩衝區的大小
		* void setRepository(java.io.File repository)		-- 設置臨時文件的存儲目錄(上傳的文件超過了緩衝區的大小,產生臨時文件)
	
	3.總結
		* 上述的這兩個方法,若是不設置都有默認值的。
	
----------
	
**ServletFileUpload類(解析request)**
	
	1.ServletFileUplod	表明的文件上傳的類,做用:用來解析request請求。
	2.方法
		* ServletFileUpload(FileItemFactory fileItemFactory)
		* static boolean isMultipartContent(javax.servlet.http.HttpServletRequest request)		-- 判斷表單的enctype值設置的是否正確
		* java.util.List parseRequest(javax.servlet.http.HttpServletRequest request)			-- 解析request請求,返回的是List集合
		* void setHeaderEncoding(java.lang.String encoding)										-- 解決中文文件名稱亂碼的問題。
		* void setFileSizeMax(long fileSizeMax)													-- 設置單個上傳文件的大小
		* void setSizeMax(long sizeMax)															-- 設置總大小
	
	3.總結(掌握)
		* parseRequest(request)		-- 解析request請求
		* setHeaderEncoding()		-- 解決中文亂碼問題呢
		* setSizeMax()				-- 設置上傳文件的總大小	
		* void setFileSizeMax()
	
----------
	
**FileItem接口(文件項)**
	
	1.FileItem類:表明文件項(普通表單項(文本框、密碼、單選),又有可能文件的上傳項)
	2.方法
		* boolean isFormField()	
			* 判斷當前的fileItem對象是不是普通表單項仍是文件上傳項?若是返回true,說明是普通表單項,若是是false,是文件上傳項
		
		* 若是是普通表單項(文本框 密碼框 複選框 單選框 下拉列表)
			* java.lang.String getFieldName()					-- 獲取的表單中的name屬性的值(例如:filedesc)
			* java.lang.String getString()						-- 獲取到用戶輸入的值(沒有解決亂碼的問題)
			* java.lang.String getString(String encoding)		-- 獲取到用戶輸入的值(解決中文亂碼問題)
		
		* 若是是文件上傳項
			* java.lang.String getName()						-- 獲取的上傳文件的名稱(ServletFileUpload類中setHeaderEncoding()解決中文亂碼)
			* java.io.InputStream getInputStream()				-- 獲取到上傳文件的輸入流
			* void write(java.io.File file)						-- 直接寫入文件
			* void delete()										-- 刪除臨時文件的(注意:刪除的代碼須要放在流關閉以後)
	
	3.總結
		* 上述全部	
	
----------
	
**文件上傳存在的問題**
	
	1.第一個問題:若是使用的是IE6瀏覽器,存在問題。
		* 若是是IE6的瀏覽器,獲取的文件的名稱是:C:\class\resource\hello.txt
		
		* 若是瀏覽器是IE的一些版本(IE6確定存在該問題),若是使用的是IE6版本的瀏覽器,選擇文件的時候,選擇完文件,點擊上傳。
		* 在Servlet中獲取到的文件名稱是包含文件的路徑的。
	
	2.第二個問題:request.getParameter()方法已經不能獲取到表單的內容了。(重要的)
		* 使用request對象的時候,request.getParameter()方法,在文件上傳中,使用的enctype="multipart/form-data"方式,那麼request.getParameter()獲取不到值了。
	
	3,注意;	request.getParameter()已經不能獲取到值了!!!

upload.jsp:javascript

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h3>文件的上傳</h3>

<form action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data">
	文件描述:<input type="text" name="filedesc"/><br/>
	文件上傳:<input type="file" name="upload"/><br/>
	<input type="submit" value="上傳"/>
</form>
</body>
</html>

UploadServlet:html

public class UploadServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		/**
		 * 1.建立一個工廠類
		 * 2.建立能解析request對象的類
		 * 3.解析request請求
		 * 4.返回的是List集合
		 * 5.遍歷集合,獲取到每個FileItem
		 * 6.操做FileItem中方法完成文件的上傳
		 */
		//判斷,表單的enctype屬性值是否設置正確,返回true,說明設置正確。返回false,不正確
		if(!ServletFileUpload.isMultipartContent(request)){
			//說明設置不正確
			throw new RuntimeException("親,您沒有設置正確的enctype屬性的值");
		}
		
		
		//1.建立工廠類
		DiskFileItemFactory factory=new DiskFileItemFactory();
		
		//設置緩衝區的大小 設置2M
		factory.setSizeThreshold(2*1024*1024);
		//設置臨時文件的存儲目錄
		String tempPath=this.getServletContext().getRealPath("/temp");
		System.out.println(tempPath);
		//建立文件目錄
		File tempFile=new File(tempPath);
		
		factory.setRepository(tempFile);
		
		//2.建立能解析request對象的類
		ServletFileUpload upload=new ServletFileUpload(factory);
		
		//設置頭的編碼,解決中文文件名稱亂碼的問題
		upload.setHeaderEncoding("utf-8");
		//設置文件上傳的總大小 4M
		upload.setSizeMax(4*1024*1024);
		
		try {
			//3.解析request請求
			//4.返回的是List集合
			List<FileItem> list=upload.parseRequest(request);
			//5.遍歷集合,獲取到每個FileItem
			for (FileItem fileItem : list) {
				//須要判斷,當前的fileItem是不是文件描述仍是文件上傳
				//isFormField(),返回true,說明表單的字段(text,password,checkbox,radio)
				if(fileItem.isFormField()){
					
					//獲取表單中name屬性的值
					String name=fileItem.getFieldName();
					
					//文件描述,獲取用戶輸入的值
					String value= fileItem.getString();
					String value_=fileItem.getString("UTF-8");
					
					System.out.println(name+":::"+value+value_);
					
				}else{
					//返回false,說明type="file" 說明是文件上傳,須要獲取用戶上傳的文件的文件名稱
					String fileName=fileItem.getName();
					
					//生成惟一的文件的名稱
					String uuid=UUID.randomUUID().toString();
					//名稱徹底換掉hello.txt --> ffggerwefd.txt
					int i=fileName.lastIndexOf(".");
					//文件的後綴名
					String lastName=fileName.substring(i);
					String uuidName=uuid+"_"+lastName;
					
					//獲取到的是文件的輸入流
					InputStream in=fileItem.getInputStream();
					
					//獲取upload文件夾的絕對路徑
					String path=this.getServletContext().getRealPath("/upload");
					System.out.println("upload文件夾的絕對路徑:"+path);
					//建立輸出流
					OutputStream out=new FileOutputStream(path+"/"+uuidName);
					byte[] by=new byte[1024];
					int len=0;
					while((len=in.read(by))!=-1){
						out.write(by, 0 ,len);
					}
					out.close();
					in.close();
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}

 

**多文件上傳(js控制多個上傳輸入項)**
	
	1.多文件上傳
		* 需求:點擊添加按鈕,生成多個文件的上傳項。點擊刪除的按鈕,刪除該個上傳項。點擊上傳按鈕,把選擇的全部的文件上傳到服務器端。
		* 前臺和後臺

moreupload.jsp:java

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>
<script type="text/javascript">
	$(function(){
		$("input[type='button']").click(function(){
			
			//建立div
			var $div=$("<div></div>");
			
			//建立選擇框
			var $input=$("<input type='file' name='upload'/>");
			var $del=$("<input type='button' value='刪除'/><br/>");
			
			//給刪除按鈕綁定事件
			$del.click(function(){
				//刪除一行,小div
				$(this).parent().remove();
			});
			
			$div.append($input);
			$div.append($del);
			
			//生成的小div存入大的div
			$("#divId").append($div);
		});
		
	});
</script>
</head>
<body>

<h3>多文件的上傳</h3>
<form action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data">
	<input type="button" value="添加" />
	<input type="submit" value="上傳"/>
	
	<!-- div,存放生成文件的選擇項 -->
	<div id="divId"></div>
</form>
</body>
</html>

  

案例:上傳圖書封面jquery

AddServlet:apache

/**
 * 添加商品(包含文件的上傳)
 * @author mjl
 *
 */
public class AddProduct extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		DiskFileItemFactory factory=new DiskFileItemFactory();
		ServletFileUpload upload=new ServletFileUpload(factory);
		//解決中文文件名稱亂碼問題
		upload.setHeaderEncoding("utf-8");
		
		//建立一個Map,存入用戶輸入的值
		Map<String,String> map=new HashMap();
		Product product=new Product();
		String uuidName=null;
		try {
			List<FileItem> list = upload.parseRequest(request);
			for (FileItem fileItem : list) {
				if(fileItem.isFormField()){
					//獲取到每一個表單項的name的值
					String name=fileItem.getFieldName();
					//獲取到用戶輸入的值
					String value=fileItem.getString("utf-8");
					//存入到map集合  map: pname 故事會  price 10
					map.put(name, value);
					
				}else{
					String fileName=fileItem.getName();
					if(fileName!=null && !fileName.trim().isEmpty()){
						
						String uuid=MyUUIDUtils.getUUID();
						int i=fileName.lastIndexOf(".");
						String lastName=fileName.substring(i);
						//惟一的文件名稱
						uuidName=uuid+lastName;
						
						InputStream in=fileItem.getInputStream();
						
						String path=this.getServletContext().getRealPath("/bookcover");
						System.out.println(path);
						OutputStream out=new FileOutputStream(path+"/"+uuidName);
						int len=0;
						byte[] by=new byte[1024];
						while((len=in.read(by))!=-1){
							out.write(by, 0, len);
						}
						out.close();
						in.close();
						fileItem.delete();
					}
				}
			}			
			//使用BeanUtils來封裝數據
			BeanUtils.populate(product, map);
			product.setImgUrl(uuidName);
			
			ProductService ps=new ProductService();
			ps.save(product);
			
			//若是添加成功了,跳轉查詢全部商品的方法
			response.sendRedirect(request.getContextPath()+"/product?method=findAll");
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

 

文件下載:瀏覽器

download.jsp:服務器

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

<h3>文件下載的頁面</h3>
<h4><a href="${pageContext.request.contextPath }/download?filename=大二.jpg">大二.jpg</a></h4>
<h4><a href="${pageContext.request.contextPath }/download?filename=guoguo.jpg">guoguo.jpg</a></h4>
<h4><a href="${pageContext.request.contextPath }/download?filename=wangwang.txt">wangwang.txt</a></h4>

</body>
</html>

DownloadServlet:app

/**
 * 文件的下載
 * @author mjl
 *
 */
public class DownloadServlet extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//先獲取文件的名稱
		String filename=request.getParameter("filename");
		
		//兩個頭(響應頭),一個流(文件的輸入流)
		//content-Type 表明要下載文件的MIME的類型    txt=text/plain jpg=image/jpeg
		//response.senContentType("text/html;charset=utf-8");
		String mimeType=getServletContext().getMimeType(filename);
		System.out.println("文件的MIME類型:"+mimeType);
		response.setContentType(mimeType);
		
		//彈出下載的窗口 Content-Disposition 值 attachment;filenmae=加上文件名稱
		response.setHeader("Content-Disposition", "attachment;filename="+filename);
		
		
		//獲取download的路徑
		String path=this.getServletContext().getRealPath("/download");
		InputStream in=new FileInputStream(path+"/"+filename);
		//使用response對象,響應
		OutputStream out=response.getOutputStream();
		byte[] by=new byte[1024];
		int len=0;
		while((len=in.read(by))!=-1){
			out.write(by,0,len);
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}
}
相關文章
相關標籤/搜索