嘿,熊dei,你不得不知道在Web開發中,文件上傳和下載功能是很是經常使用的功能,關於文件上傳,瀏覽器上傳【文件以流的形式傳輸】——>服務器端——>Servlet獲取上傳文件的輸入流——>解析請求參數,這一系列過程下來我這佩奇腦袋都疼,所以我更推薦用apache的開源工具common-fileupload這個文件上傳組件,common-fileupload上傳組件的jar包能夠去apache官網上面下載,也能夠在struts的lib文件夾下面找到(不要問我爲何,由於就算你問我我也不會告訴你struts上傳功能就是基於這個實現,固然你也不必定用過Struts【如今不用去學,用的少了】,再者你也不會這麼閒去lib目錄找),其次common-fileupload依賴於common-io包,因此須要一塊兒下載使用!javascript
jar包下載,能夠直接搜索apche官網進行下載,不過如今比較流行mawen管理jar包(不懂mawen?加油吧,要學的東西還不少,mawen是必定要學的並且也很易學,用了mawen你就停不下來,這玩意太便捷了,學會了mawen,你就會明白媽媽爲何不再用擔憂小明拿U盤去拷小紅的jar包了) html
這個時候common-fileupload依賴的common-io包一樣的操做進行下載,以後建立項目,引入jar包<%@ 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>
複製代碼
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);
}
}
複製代碼
一、爲保證服務器安全,上傳文件應該放在外界沒法直接訪問的目錄下,好比放於WEB-INF目錄下。java
二、爲防止文件覆蓋的現象發生,要爲上傳文件產生一個惟一的文件名。 三、若是上傳的目錄在Tomcat目錄中的wtpwebapps下的新建文件夾名爲upload ,以下:web
則須要注意: 3.1. 若是修改代碼,則在tomcat從新啓動時 會被刪除 緣由:當修改代碼的時候,tomcat會從新編譯一份新的class 而且從新部署(從新建立各類目錄)3.2.若是不修改代碼,則不會刪除 緣由: 沒有修改代碼,class仍然是以前的class apache
所以, 爲了防止 上傳目錄丟失: a. 虛擬路徑 b. 直接更換上傳目錄到非tomcat目錄 四、限制上傳:限制類型、限制大小。注意 對文件的限制條件 寫在parseRequest以前下載:不須要依賴任何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
複製代碼
文件下載代碼:tomcat
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: 連接:pan.baidu.com/s/1oyyEkctc… 提取碼:30e7安全