一、前言
在Javaweb中,上傳下載是經(jīng)常用到的功能,對于文件上傳,瀏覽器在上傳的過程中是以流的過程將文件傳給服務(wù)器,一般都是使用commons-fileupload這個包實現(xiàn)上傳功能,因為commons-fileupload依賴于commons-io這個包,所以需要下載這兩個包c(diǎn)ommons-fileupload-1.2.1.jar和commons-io-1.3.2.jar,筆者已經(jīng)打包好(點(diǎn)擊下載)
1、搭建環(huán)境
創(chuàng)建Web項目,將包導(dǎo)入到項目lib下

2、實現(xiàn)文件上傳
(第一種上傳的方法)
新建upload.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>upload file</title>
</head>
<body>
<!--這里的<%=request.getContextPath()%>是表示項目的絕對路徑,也就是說不管你以后將項目拷貝到哪個位置,它都會找到準(zhǔn)確的路徑 -->
<form action="<%=request.getContextPath()%>/uploadServlet" enctype="multipart/form-data" method="post">
<span>選擇文件:</span><input type="file" name="file1">
<input type="submit" value="上傳">
</form>
</body>
</html>
新建處理文件上傳的Servlet
package com.load;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@WebServlet("/uploadServlet")
public class uploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public uploadServlet() {
super();
}
/* fileupload 包中, HTTP 請求中的復(fù)雜表單元素都被看做一個 FileItem 對象;
* FileItem 對象必須由 ServletFileUpload 類中的 parseRequest() 方法解析 HTTP 請求
* (即被包裝之后的 HttpServletRequest 對象)出來,即分離出具體的文本表單和上傳文件
* */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//通過isMultipartContent()方法:分析請求里面是不是有文件上的請求,
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if(isMultipart){
//創(chuàng)建可設(shè)置的磁盤節(jié)點(diǎn)工廠
DiskFileItemFactory factory = new DiskFileItemFactory();
//獲取請求的上下文信息
ServletContext servletContext = request.getServletContext();
//緩存目錄,每個服務(wù)器特定的目錄
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
//設(shè)置服務(wù)器的緩存目錄
factory.setRepository(repository);
//ServletFileUpload 對象的創(chuàng)建需要依賴于 FileItemFactory
//工廠將獲得的上傳文件 FileItem 對象保存至服務(wù)器硬盤,即 DiskFileItem 對象。
ServletFileUpload upload = new ServletFileUpload(factory);
try {
//解析即被包裝之后的 HttpServletRequest對象,既是分離文本表單和上傳文件(http請求會被包裝為HttpServletRequest)
List<FileItem> items = upload.parseRequest(request);
for(FileItem item:items){
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
//實例化一個文件
//request.getRealPath(獲取真實路徑)
File file = new File(request.getRealPath("/")+"/loads"+fileName.substring(fileName.lastIndexOf("\\")+1,fileName.length()));
item.write(file);
}
} catch (FileUploadException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(第二種上傳的方法)
新建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>upload file</title>
</head>
<body>
<!--這里的<%=request.getContextPath()%>是表示項目的絕對路徑,也就是說不管你以后將項目拷貝到哪個位置,它都會找到準(zhǔn)確的路徑 -->
<form action="<%=request.getContextPath()%>/uploadservlet1" enctype="multipart/form-data" method="post">
<span>選擇文件:</span><input type="file" name="file1">
<input type="submit" value="上傳">
</form>
</body>
</html>
JSP頁面
建立Servlet處理上傳
package com.load;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@WebServlet("/uploadservlet1")
@MultipartConfig(location="")
public class uploadservlet1 extends HttpServlet {
private static final long serialVersionUID = 1L;
public uploadservlet1() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
request.setCharacterEncoding("utf-8");
//取得上傳文件,讀取文件
Part part = request.getPart("file1");
//定義一個變量去接收文件名
String filename = null;
//Content-Disposition: 就是當(dāng)用戶想把請求所得的內(nèi)容存為一個文件的時候提供一個默認(rèn)的文件名
//Content-Disposition:告訴瀏覽器以下載的方式打開文件
for (String content : part.getHeader("content-disposition").split(";")) {
System.out.println(content);
//取得文件名
if (content.trim().startsWith("filename")) {
//截取文件名
filename = content.substring(
content.indexOf('=') + 1).trim().replace("\"", "");
}
}
//輸出流
OutputStream out = null;
//輸入流
InputStream filecontent = null;
//File.separator 取得系統(tǒng)的分割線等數(shù)據(jù)
out = new FileOutputStream(new File("e:/loads" + File.separator + filename));
int read;
//獲得一個輸入流
filecontent = part.getInputStream();
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
System.out.println("New file " + filename + " created at " + "/loads");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
(第三種上傳的方法)
這里使用的是jspSmartUpload包上傳下載,筆者認(rèn)為這種上傳下載較為簡單,但是好像不是很多人用,不懂,下載地址在這里(點(diǎn)我下載)
創(chuàng)建HTML頁面
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上傳文件</title>
</head>
<body>
<p> </p>
<p align="center">上傳文件選擇</p>
<form method="post" Action="../DouploadServlet" enctype="multipart/form-data">
<table width="75%" border="1" align="center">
<tr><td><div align="center">
1.<input type="file" name="file1" >
</div></td></tr>
<tr><td><div align="center">
2.<input type="file" name="file2" >
</div></td></tr>
<tr><td><div align="center">
3.<input type="file" name="file3" >
</div></td></tr>
<tr><td><div align="center">
<input type="submit" name="Submit" value="上傳他">
</div></td></tr>
</table>
</form>
</body>
</html>
創(chuàng)建Servlet處理上傳文件
package com.load;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.PageContext;
import com.jspsmart.upload.File;
import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;
@WebServlet("/DouploadServlet")
public class DouploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DouploadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//新建一個智能上傳對象
SmartUpload su = new SmartUpload();
/*
* PageContext pageContext;
HttpSession session;
ServletContext application;
ServletConfig config;
JspWriter out;
Object page = this;
HttpServletRequest request,
HttpServletResponse response
其中page對象,request和response已經(jīng)完成了實例化,而其它5個沒有實例化的對象通過下面的方式實例化
pageContext = jspxFactory.getPageContext(this, request, response,null, true, 8192, true);
*/
//通過Jsp工廠類獲取上下文環(huán)境
PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true);
//上傳初始化
su.initialize(pagecontext);
//上傳文件
try {
su.upload();
//將上傳文件保存到指定目錄
int count = su.save("/share");
out.println(count+"個文件上傳成功!<br>"+su.toString());
} catch (SmartUploadException e) {
e.printStackTrace();
}
//逐個提取上傳文件信息
for(int i=0;i<su.getFiles().getCount();i++){
File file = su.getFiles().getFile(i);
//如果文件不存在
if(file.isMissing()) continue;
//顯示當(dāng)前文件信息
out.println("<table border=1>");
out.println("<tr><td>表單項名(FieldName)</td></td>"+file.getFieldName()+"</td></tr>");
out.println("<tr><td>文件長度</td><td>"+file.getSize()+"</td></tr>");
out.println("<tr><td>文件名</td><td>"+file.getFileName()+"</td></tr>");
out.println("<tr><td>文件擴(kuò)展名</td><td>"+file.getFileExt()+"</td></tr>");
out.println("<tr><td>文件全名</td><td>"+file.getFilePathName()+"</td></tr>");
out.println("</table><br>");
}
}
/**
* @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);
}
}
3、實現(xiàn)文件下載
(第一種文件下載)
注意:該代碼是直接訪問Servlet類的
package com.load;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//直接使用Http://localhost:8080/Test1/download進(jìn)行下載,但是這個有缺陷,如果下載文件名中有中文,就會變成亂碼現(xiàn)象!
@WebServlet("/download")
public class download extends HttpServlet {
private static final long serialVersionUID = 1L;
public download() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain;charset=utf-8");
response.setCharacterEncoding("utf-8");
response.setHeader("Location","中文.txt");
response.setHeader("Content-Disposition", "attachment; filename=" + "賬號.txt");
OutputStream outputStream = response.getOutputStream();
InputStream inputStream = new FileInputStream("E:/loads"+"/賬號.txt");
byte[] buffer = new byte[1024];
int i = -1;
while ((i = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, i);
}
outputStream.flush();
outputStream.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(第二種下載方法)
新建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>下載</title>
</head>
<body>
<a href="../DoDownloadServlet?filename=呵呵.txt">點(diǎn)擊下載</a>
</body>
</html>
Jsp頁面代碼
創(chuàng)建Servlet類進(jìn)行下載(注意:該下載如果文件名是中文的話,一樣會出現(xiàn)亂碼現(xiàn)象)
package com.load;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.PageContext;
import org.hsqldb.lib.StringUtil;
import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;
@WebServlet("/DoDownloadServlet")
public class DoDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DoDownloadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//得到下載文件的名稱
//String filename = request.getParameter("filename");
//String filename = new String(FileName.getBytes("iso8859-1"),"UTF-8");
//新建SmartUpload對象
SmartUpload su = new SmartUpload();
PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true);
//上傳初始化
su.initialize(pagecontext);
//設(shè)置禁止打開該文件
su.setContentDisposition(null);
//下載文件
try {
su.downloadFile("/listener/"+filename);
} catch (SmartUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
(第三種下載的方法)
同上的jsp頁面代碼,這里就不再重復(fù)了。
新建Serlvet類,實現(xiàn)下載功能(注意:這里文件名就算是中文名,也不會出現(xiàn)亂碼問題了?。?/p>
package com.load;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspFactory;
import javax.servlet.jsp.PageContext;
import org.hsqldb.lib.StringUtil;
import com.jspsmart.upload.SmartUpload;
import com.jspsmart.upload.SmartUploadException;
@WebServlet("/DoDownloadServlet")
public class DoDownloadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public DoDownloadServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//獲得文件名稱
String path1 = request.getParameter("filename");
//獲得路徑名稱
String path = request.getSession().getServletContext().getRealPath("/listener/"+path1);
// path是根據(jù)日志路徑和文件名拼接出來的
File file = new File(path);
String filename = file.getName();
try {
//判斷是否是IE11
Boolean flag= request.getHeader("User-Agent").indexOf("like Gecko")>0;
//IE11 User-Agent字符串:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
//IE6~IE10版本的User-Agent字符串:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.0; Trident/6.0)
if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") >0||flag){
filename = URLEncoder.encode(filename, "UTF-8");//IE瀏覽器
}else {
//先去掉文件名稱中的空格,然后轉(zhuǎn)換編碼格式為utf-8,保證不出現(xiàn)亂碼,
//這個文件名稱用于瀏覽器的下載框中自動顯示的文件名
filename = new String(filename.replaceAll(" ", "").getBytes("UTF-8"), "ISO8859-1");
//firefox瀏覽器
//firefox瀏覽器User-Agent字符串:
//Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
} InputStream fis = new BufferedInputStream(new FileInputStream(path));
byte[] buffer;
buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" +filename);
response.addHeader("Content-Length", "" + file.length());
OutputStream os = response.getOutputStream();
response.setContentType("application/octet-stream");
os.write(buffer);// 輸出文件
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(filename);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}