javaWeb學習總結——文件上傳、下載


@


嘿,熊dei,你不得不知道在Web開發中,文件上傳和下載功能是非常常用的功能,關於文件上傳,瀏覽器上傳【文件以流的形式傳輸】——>服務器端——>Servlet獲取上傳文件的輸入流——>解析請求參數,這一系列過程下來我這佩奇腦殼都疼,因此我更 推薦用apache的開源工具common-fileupload這個文件上傳組件,common-fileupload上傳組件的jar包可以去apache官網上面下載,也可以在struts的lib文件夾下面找到(不要問我為什么,因為就算你問我我也不會告訴你struts上傳功能就是基於這個實現,當然你也不一定用過Struts【現在不用去學,用的少了】,再者你也不會這么閑去lib目錄找),其次 common-fileupload依賴於 common-io包,所以需要一起下載使用!

1、文件上傳環境搭建

jar包下載,可以直接搜索apche官網進行下載,不過現在比較流行mawen管理jar包(不懂mawen?加油吧,要學的東西還很多,mawen是一定要學的而且也很易學,用了mawen你就停不下來,這玩意太便捷了,學會了mawen,你就會明白媽媽為什么再也不用擔心小明拿U盤去拷小紅的jar包了)
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
這個時候common-fileupload依賴的common-io包同樣的操作進行下載,之后創建項目,引入jar包
在這里插入圖片描述

2、文件上傳代碼實現

2.1JSP代碼

<%@ 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>											
		<form action="UploadServet" method="post"  enctype="multipart/form-data">
			學號:<input name="sno" /><br/>
			姓名:<input name="sname" /><br/>
			上傳照片: <input type="file"  name="spicture"/>
			<br/>
			<input type="submit" value="注冊"/>
		</form>
		<a href="DownloadServlet?filename=MIME.png">MIME</a>
		
</body>
</html>

在這里插入圖片描述

2.2Servlet代碼

package org.student.servlet;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet implementation class UploadServet
 */
public class UploadServet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public UploadServet() {
		super();
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html; charset=UTF-8");
		// 上傳
		// request.getParameter("sname")
		try {
			boolean isMultipart = ServletFileUpload.isMultipartContent(request);
			if (isMultipart) {// 判斷前台的form是否有 mutipart屬性
//				FileItemFactory factory = new DiskFileItemFactory();
				DiskFileItemFactory factory = new DiskFileItemFactory();
				
				ServletFileUpload upload = new ServletFileUpload(factory);
				
				//設置上傳文件時 用到的臨時文件的大小DiskFileItemFactory
				factory.setSizeThreshold(10240);//設置臨時的緩沖文件大小為10
				factory.setRepository(new File("D:\\study\\uploadtemp"));//設置臨時文件的目錄
				//控制上傳單個文件的大小  20KB ServletFileUpload
				upload.setSizeMax(20480);//字節B
				Thread.sleep(3000);
				
				// 通過parseRequest解析form中的所有請求字段,並保存到 items集合中(即前台傳遞的sno sname
				// spicture此時就保存在了items中)
				List<FileItem> items = upload.parseRequest(request);
				// 遍歷items中的數據(item=sno sname spicture)
				Iterator<FileItem> iter = items.iterator();
				while (iter.hasNext()) {
					FileItem item = iter.next();
					String itemName = item.getFieldName();
					int sno = -1;
					String sname = null;
					// 判斷前台字段 是普通form表單字段(sno sname),還是文件字段

					// request.getParameter() -- iter.getString()
					if (item.isFormField()) {
						if (itemName.equals("sno")) {// 根據name屬性 判斷item是sno sname 還是spicture?
							sno = Integer.parseInt(item.getString("UTF-8"));
						} else if (itemName.equals("sname")) {
							sname = item.getString("UTF-8");
						} else {
							System.out.println("其他字段xxx.....");
						}
					} else {// spicture 123
							// 文件 上傳
							// 文件名 getFieldName是獲取 普通表單字段的Name值
							// getName()是獲取 文件名
						String fileName = item.getName();//a.txt   a.docx   a.png
						String ext = fileName.substring(  fileName.indexOf(".")+1 ) ;
						if(!(ext.equals("png") || ext.equals("gif") ||ext.equals("jpg"))) {
							System.out.println("圖片類型有誤!格式只能是 png gif  jpg");
							return ;//終止
						}
						// 獲取文件內容 並上傳
						// 定義文件路徑:指定上傳的位置(服務器路徑)
						// 獲取服務器路徑D:\\study\\apache-tomcat-8.5.30\\wtpwebapps\\UpAndDown\\upload
						// String path =request.getSession().getServletContext().getRealPath("upload") ;
						String path = "D:\\study\\upload";

						File file = new File(path, fileName);
						
					

						item.write(file);// 上傳
						System.out.println(fileName + "上傳成功!");
						return;
					}
				}

			}

		}
		catch (FileUploadBase.SizeLimitExceededException e) {//SizeLimitExceededException是FileUploadException的一個子類
			System.out.println("上傳文件大小超過限制!最大20KB");
		}
		catch (FileUploadException e) 
		{
			e.printStackTrace();
			
		}
		
		// 解析請求
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

2.3 文件上傳注意的問題:

1、為保證服務器安全,上傳文件應該放在外界無法直接訪問的目錄下,比如放於WEB-INF目錄下。

  2、為防止文件覆蓋的現象發生,要為上傳文件產生一個唯一的文件名。
  
3、如果上傳的目錄在Tomcat目錄中的wtpwebapps下的新建文件夾名為upload ,如下:

在這里插入圖片描述
則需要注意:
3.1.如果修改代碼,則在tomcat重新啟動時 會被刪除
原因:當修改代碼的時候,tomcat會重新編譯一份新的class 並且重新部署(重新創建各種目錄)

3.2.如果不修改代碼,則不會刪除
原因: 沒有修改代碼,class仍然是之前的class
在這里插入圖片描述
因此,為了防止 上傳目錄丟失: a.虛擬路徑
在這里插入圖片描述
b.直接更換上傳目錄到非tomcat目錄
在這里插入圖片描述
4、限制上傳:限制類型、限制大小。注意 對文件的限制條件 寫在parseRequest之前
在這里插入圖片描述

3、關於下載

下載:不需要依賴任何jar
a.請求(地址a form),請求Servlet
b.Servlet通過文件的地址 將文件轉為輸入流 讀到Servlet中
c.通過輸出流 將 剛才已經轉為輸入流的文件 輸出給用戶
注意:下載文件 需要設置2個 響應頭:

response.addHeader("content-Type","application/octet-stream" );//MIME類型:二進制文件(任意文件)
response.addHeader("content-Disposition","attachement;filename="+fileName );//fileName包含了文件后綴:abc.txt

文件下載代碼:

package org.student.servlet;

import java.io.IOException;
import java.io.InputStream;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class DownloadServlet
 */
public class DownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public DownloadServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		//獲取需要下載的文件名
		String fileName = request.getParameter("filename") ;//form  、a  href、 ...Server?a=b
		
		
		//下載文件:需要設置 消息頭
		response.addHeader("content-Type","application/octet-stream" );//MIME類型:二進制文件(任意文件)
		response.addHeader("content-Disposition","attachement;filename="+fileName );//fileName包含了文件后綴:abc.txt
		
		//Servlet通過文件的地址  將文件轉為輸入流 讀到Servlet中
		InputStream in = getServletContext().getResourceAsStream("/res/MIME.png") ;
		
		//通過輸出流 將 剛才已經轉為輸入流的文件  輸出給用戶
		ServletOutputStream out = response.getOutputStream() ;
		byte[] bs = new byte[10];
		int len=-1 ;
		while(  (len=in.read(bs)) != -1) {
			out.write(bs,0,len);
		}
		out.close();
		in.close();
		
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

到這里,到了最開心的時刻了!!!關於文件上傳下載的源碼與筆記已經打包好了QnQ:
鏈接:https://pan.baidu.com/s/1oyyEkctcvY3AvTsJNkiuuQ 提取碼:30e7


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM