Javaweb實(shí)現(xiàn)上傳下載文件的多種方法
在Javaweb中,上傳下載是經(jīng)常用到的功能,對(duì)于文件上傳,瀏覽器在上傳的過(guò)程中是以流的過(guò)程將文件傳給服務(wù)器,一般都是使用commons-fileupload這個(gè)包實(shí)現(xiàn)上傳功能,因?yàn)閏ommons-fileupload依賴(lài)于commons-io這個(gè)包,所以需要下載這兩個(gè)包c(diǎn)ommons-fileupload-1.2.1.jar和commons-io-1.3.2.jar。
1、搭建環(huán)境
創(chuàng)建Web項(xiàng)目,將包導(dǎo)入到項(xiàng)目lib下
2、實(shí)現(xiàn)文件上傳
(第一種上傳的方法)
新建upload.jsp頁(yè)面
<%@ 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()%>是表示項(xiàng)目的絕對(duì)路徑,也就是說(shuō)不管你以后將項(xiàng)目拷貝到哪個(gè)位置,它都會(huì)找到準(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 請(qǐng)求中的復(fù)雜表單元素都被看做一個(gè) FileItem 對(duì)象; * FileItem 對(duì)象必須由 ServletFileUpload 類(lèi)中的 parseRequest() 方法解析 HTTP 請(qǐng)求 * (即被包裝之后的 HttpServletRequest 對(duì)象)出來(lái),即分離出具體的文本表單和上傳文件 * */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通過(guò)isMultipartContent()方法:分析請(qǐng)求里面是不是有文件上的請(qǐng)求, boolean isMultipart = ServletFileUpload.isMultipartContent(request); if(isMultipart){ //創(chuàng)建可設(shè)置的磁盤(pán)節(jié)點(diǎn)工廠(chǎng) DiskFileItemFactory factory = new DiskFileItemFactory(); //獲取請(qǐng)求的上下文信息 ServletContext servletContext = request.getServletContext(); //緩存目錄,每個(gè)服務(wù)器特定的目錄 File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); //設(shè)置服務(wù)器的緩存目錄 factory.setRepository(repository); //ServletFileUpload 對(duì)象的創(chuàng)建需要依賴(lài)于 FileItemFactory //工廠(chǎng)將獲得的上傳文件 FileItem 對(duì)象保存至服務(wù)器硬盤(pán),即 DiskFileItem 對(duì)象。 ServletFileUpload upload = new ServletFileUpload(factory); try { //解析即被包裝之后的 HttpServletRequest對(duì)象,既是分離文本表單和上傳文件(http請(qǐng)求會(huì)被包裝為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(); //實(shí)例化一個(gè)文件 //request.getRealPath(獲取真實(shí)路徑) 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頁(yè)面(同上,只是路徑改變下)
<%@ 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()%>是表示項(xiàng)目的絕對(duì)路徑,也就是說(shuō)不管你以后將項(xiàng)目拷貝到哪個(gè)位置,它都會(huì)找到準(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>
建立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"); //定義一個(gè)變量去接收文件名 String filename = null; //Content-Disposition: 就是當(dāng)用戶(hù)想把請(qǐng)求所得的內(nèi)容存為一個(gè)文件的時(shí)候提供一個(gè)默認(rèn)的文件名 //Content-Disposition:告訴瀏覽器以下載的方式打開(kāi)文件 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)的分割線(xiàn)等數(shù)據(jù) out = new FileOutputStream(new File("e:/loads" + File.separator + filename)); int read; //獲得一個(gè)輸入流 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)為這種上傳下載較為簡(jiǎn)單,但是好像不是很多人用,不懂。
創(chuàng)建HTML頁(yè)面
<!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(); //新建一個(gè)智能上傳對(duì)象 SmartUpload su = new SmartUpload(); /* * PageContext pageContext; HttpSession session; ServletContext application; ServletConfig config; JspWriter out; Object page = this; HttpServletRequest request, HttpServletResponse response 其中page對(duì)象,request和response已經(jīng)完成了實(shí)例化,而其它5個(gè)沒(méi)有實(shí)例化的對(duì)象通過(guò)下面的方式實(shí)例化 pageContext = jspxFactory.getPageContext(this, request, response,null, true, 8192, true); */ //通過(guò)Jsp工廠(chǎng)類(lèi)獲取上下文環(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+"個(gè)文件上傳成功!<br>"+su.toString()); } catch (SmartUploadException e) { e.printStackTrace(); } //逐個(gè)提取上傳文件信息 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>表單項(xiàng)名(FieldName)</td></td>"+file.getFieldName()+"</td></tr>"); out.println("<tr><td>文件長(zhǎng)度</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); } }
注意:代碼 int count = su.save("/share");表示你需要先建個(gè)文件夾,所以你可以先在Webcontent建立一個(gè),然后將項(xiàng)目取消部署,再重新部署進(jìn)去之后就會(huì)在運(yùn)行那邊建立起一個(gè)文件夾了!
或者你可以直接找到運(yùn)行的路徑,然后建立share文件夾。
3、實(shí)現(xiàn)文件下載
(第一種文件下載)
注意:該代碼是直接訪(fǎng)問(wèn)Servlet類(lèi)的
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)行下載,但是這個(gè)有缺陷,如果下載文件名中有中文,就會(huì)變成亂碼現(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=" + "賬號(hào).txt"); OutputStream outputStream = response.getOutputStream(); InputStream inputStream = new FileInputStream("E:/loads"+"/賬號(hào).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頁(yè)面選擇下載
<%@ 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>
創(chuàng)建Servlet類(lèi)進(jìn)行下載(注意:該下載如果文件名是中文的話(huà),一樣會(huì)出現(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 { //得到下載文件的名稱(chēng) //String filename = request.getParameter("filename"); //String filename = new String(FileName.getBytes("iso8859-1"),"UTF-8"); //新建SmartUpload對(duì)象 SmartUpload su = new SmartUpload(); PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true); //上傳初始化 su.initialize(pagecontext); //設(shè)置禁止打開(kāi)該文件 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頁(yè)面代碼,這里就不再重復(fù)了。
新建Serlvet類(lèi),實(shí)現(xiàn)下載功能(注意:這里文件名就算是中文名,也不會(huì)出現(xiàn)亂碼問(wèn)題了?。?br />
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 { //獲得文件名稱(chēng) String path1 = request.getParameter("filename"); //獲得路徑名稱(chēng) String path = request.getSession().getServletContext().getRealPath("/listener/"+path1); // path是根據(jù)日志路徑和文件名拼接出來(lái)的 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 { //先去掉文件名稱(chēng)中的空格,然后轉(zhuǎn)換編碼格式為utf-8,保證不出現(xiàn)亂碼, //這個(gè)文件名稱(chēng)用于瀏覽器的下載框中自動(dòng)顯示的文件名 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); } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
基于Java SSM的健康管理小程序的實(shí)現(xiàn)
本篇文章主要為大家分享了基于SSM健康管理小程序的設(shè)計(jì)與實(shí)現(xiàn)。感興趣的小伙伴可以了解一下2021-11-11JavaSE系列基礎(chǔ)包裝類(lèi)及日歷類(lèi)詳解
這篇文章主要介紹的是JavaSE中常用的基礎(chǔ)包裝類(lèi)以及日歷類(lèi)的使用詳解,文中的示例代碼簡(jiǎn)潔易懂,對(duì)我們學(xué)習(xí)JavaSE有一定的幫助,感興趣的小伙伴快來(lái)跟隨小編一起學(xué)習(xí)吧2021-12-12詳解Java中l(wèi)og4j.properties配置與加載應(yīng)用
這篇文章主要介紹了 log4j.properties配置與加載應(yīng)用的相關(guān)資料,需要的朋友可以參考下2018-02-02Windows環(huán)境下重啟jar服務(wù)bat代碼的解決方案
在Windows環(huán)境下部署java的jar包,若有多個(gè)服務(wù)同時(shí)啟動(dòng),很難找到相應(yīng)服務(wù)重啟,每次都重啟全部服務(wù)很麻煩,應(yīng)用場(chǎng)景大多用于部署測(cè)試,今天給大家分享Windows環(huán)境下重啟jar服務(wù)bat代碼,感興趣的朋友一起看看吧2023-08-08Java?多線(xiàn)程并發(fā)ReentrantLock
這篇文章主要介紹了Java?多線(xiàn)程并發(fā)ReentrantLock,Java?提供了?ReentrantLock?可重入鎖來(lái)提供更豐富的能力和靈活性,感興趣的小伙伴可以參考一下2022-06-06SpringBoot2整合JTA組件實(shí)現(xiàn)多數(shù)據(jù)源事務(wù)管理
這篇文章主要介紹了SpringBoot2整合JTA組件實(shí)現(xiàn)多數(shù)據(jù)源事務(wù)管理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03Java Switch對(duì)各類(lèi)型支持實(shí)現(xiàn)原理
這篇文章主要介紹了Java Switch對(duì)各類(lèi)型支持實(shí)現(xiàn)原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05SpringMVC攔截器的實(shí)現(xiàn)和作用及Redis登陸功能的優(yōu)化詳解
這篇文章主要介紹了Java項(xiàng)目SpringMVC攔截器+Redis優(yōu)化登錄功能實(shí)現(xiàn)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧2022-09-09