java 文件瀏覽器 java獲取瀏覽器下載路徑



文章插圖
java 文件瀏覽器 java獲取瀏覽器下載路徑

文章插圖

1. 增強HttpServletResponse對象
【java 文件瀏覽器 java獲取瀏覽器下載路徑】1. 實現一個增強的HttpServletResponse類 , 需要繼承javax.servlet.http.HttpServletRequestWrapper類 , 通過重寫自己需要增強的方法來實現(這種模式就叫做裝飾者模式) , 使用該增強類在加上過濾器就可以實現無編碼轉換處理代碼 。
public class MyRequest extends HttpServletRequestWrapper{private HttpServletRequest req;public MyRequest(HttpServletRequest request) {super(request);req=request;[email protected] String getParameter(String name) {//解決編碼問題 , 無論是post還是get請求 , 都不需要在業務代碼中對編碼再處理String method=req.getMethod();if("get".equalsIgnoreCase(method)){try {String str=req.getParameter(name);byte[] b=str.getBytes("iso8859-1");String newStr=new String(b, "utf-8");return newStr;} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}else if("post".equalsIgnoreCase(method)){try {req.setCharacterEncoding("utf-8");} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//絕對不能刪除此行代碼,因為此行代碼返回的就是編碼之后的數據return super.getParameter(name);}}在過濾器中應用
public class FilterTest4 implements Filter [email protected] void init(FilterConfig filterConfig) throws ServletException [email protected] void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {//生成增強的HttpServletRequest對象HttpServletRequest req=(HttpServletRequest) request;MyRequest myReq=new MyRequest(req);//將增強的HttpServletRequest對象傳入過濾器執行鏈中 , 在后面傳入的request對象都會是增強的HttpServletRequest對象chain.doFilter(myReq, response);[email protected] void destroy() {}}2. 文件上傳原理過程
1. JavaWeb中實現文件上傳:
客戶端:HTML頁面需要一個<form>表單 , 且必須設置表單的enctype屬性值為”multipart/form-data” , 以及method屬性值為”post”(因為get方式不支持大量數據提交);表單里有一個<input type=”file” name=””>的標簽 , 且name屬性值必須指定 。
<html> <head> <title>My JSP 'upload.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"> </head><body> <form action="" method="post" enctype="multipart/form-data"> <input type="text" name="name"> 請選擇文件:<input type="file" name="upload"> <input type="submit" value="http://www.mnbkw.com/jxjc/186645/上傳"> </form> </body></html>服務端:主要進行IO讀寫操作 。必須導入commons-fileupload和commons-io兩個jar包 , 可以通過請求request對象的getInputStream獲得一個流來讀取請求中的文件數據 , 但是如果客戶端上傳多個文件時 , 就會很麻煩 , 所以提供了commons-fileupload和commons-io兩個jar包來更方便的實現文件上傳 。
import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;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.FileUploadException;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;public class UploadServlet extends [email protected] void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {/** * 1. 創建磁盤文件項工廠類 DiskFileItemFactory * 2. 創建核心解析Request類 ServletFileUpload * 3. 開始解析Request對象中的數據 , 并返回一個List集合 * 4. List中包含表單中提交的內容 * 5. 遍歷集合 , 獲取內容 */DiskFileItemFactory fac=new DiskFileItemFactory();ServletFileUpload upload=new ServletFileUpload(fac);upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼try {List<FileItem> fileItems = upload.parseRequest(req);for(FileItem item:fileItems){//有可能是普通文本項 , 比如<input type="text">標簽提交上來的字符串//也有可能是<input type="submit" value="http://www.mnbkw.com/jxjc/186645/上傳">上傳的文件//文件項與普通項有不同的API來處理//首先判斷是普通文本項還是文件項 , if(item.isFormField()){//true表示普通文本項//獲取文本項的name屬性值String name=item.getFieldName();//獲取對應的文本String value=http://www.mnbkw.com/jxjc/186645/item.getString("utf-8");//防止中文亂碼System.out.println(name+":"+value);}else{//false表示文件項//先獲取文件名稱String name=item.getName();//獲取文件項的輸入流InputStream in=item.getInputStream();//獲取服務器端文件存儲的目標磁盤路徑String path=getServletContext().getRealPath("/upload");System.out.println(path);//獲取輸出流 , 輸出到本地文件中OutputStream out=new FileOutputStream(path+"/"+name);//寫入數據int len=0;byte[] b=new byte[1024];while((len=in.read(b))!=-1){out.write(b,0,len);}in.close();out.close();}}} catch (FileUploadException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}注意:在文件上傳時 , 會將form表單的屬性enctype屬性值為”multipart/form-data” , 當提交到服務端后 , 無法使用 req.getParameter(name) 方法來獲取到內容 , 只有通過上面的方法來獲取文本項 。
2. 文件上傳相關核心類:
DiskFileItemFactory:相關API如下public DiskFileItemFactory():無參構造器public DiskFileItemFactory(int sizeThreshold, File repository):構造器 , sizeThreshold設置緩沖區大小 , 默認10240 byte;repository表示如果過緩沖區空間小于上傳文件空間 , 那么會生成臨時文件 , repository就是指定該臨時文件的保存路徑 , 如果過未上傳完成就中斷 , 繼續上傳時就可以通過這個臨時文件來繼續上傳 。public void setSizeThreshold(int sizeThreshold):設置緩沖區大小public void setRepository(File repository):指定該臨時文件的保存路徑
//改進上面的文件上傳代碼 , 添加一個臨時文件public class UploadServlet extends [email protected] void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {DiskFileItemFactory fac=new DiskFileItemFactory();fac.setSizeThreshold(1024*1024);//設置緩沖區為1mb//設置臨時文件的本地磁盤存儲路徑File repository=new File(getServletContext().getRealPath("/temp"));fac.setRepository(repository);ServletFileUpload upload=new ServletFileUpload(fac);upload.setHeaderEncoding("utf-8");//防止中文的文件名亂碼try {List<FileItem> fileItems = upload.parseRequest(req);for(FileItem item:fileItems){if(item.isFormField()){String name=item.getFieldName();String value=item.getString();String value=http://www.mnbkw.com/jxjc/186645/item.getString("utf-8");//防止中文亂碼System.out.println(name+":"+value);}else{String name=item.getName();InputStream in=item.getInputStream();String path=getServletContext().getRealPath("/upload");System.out.println(path);OutputStream out=new FileOutputStream(path+"/"+name);int len=0;byte[] b=new byte[1024];while((len=in.read(b))!=-1){out.write(b,0,len);}in.close();out.close();}}} catch (FileUploadException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}ServletFileUpload:相關API如下public static final boolean isMultipartContent( HttpServletRequest request) :判斷表單提交上來的數據內容是否是multipart類型的數據 , 即 form表單的 enctype=”multipart/form-data” , 是則返回true , 否則返回falsepublic List /* FileItem */ parseRequest(HttpServletRequest request):解析request對象 , 返回一個泛型為FileItem 的List集合public void setFileSizeMax(long fileSizeMax):設置單個文件的空間大小的最大值public void setSizeMax(long sizeMax):設置所有文件空間大小之和的最大值public void setHeaderEncoding(String encoding):解決上傳文件名的亂碼問題public void setProgressListener(ProgressListener pListener):上傳時的進度條 。FileItem:封裝表單中提交的數據boolean isFormField():判斷當前FileItem對象是表單中提交的文本數據項 , 還是文件數據項String getFieldName():獲取文本項類型FileItem對象的name屬性值 , 即相當于表單中的 <input type=”text” name=”name”>String getString( String encoding ):獲取文本項類型FileItem對象的value值 , 可以指定編碼格式 , 也可以省略encoding不寫String getName():應用于文件項類型的FileItem對象 , 用于獲取文件的名稱 , 包括后綴名InputStream getInputStream():獲取輸入流void delete():刪除臨時緩存文件(在輸入以及輸出流關閉后執行)
3. 實現多文件上傳(需要js技術):主要是更改jsp頁面 , 通過js代碼來添加多個文件進行上傳 , 服務器代碼無需更改
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <base > <title>My JSP 'upload.jsp' starting page</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"> </head><body> <script type="text/javascript"> function run(){ var div=document.getElementById("divId");div.innerHTML+="<div><input type='file' name='upload'><input type='button' value='http://www.mnbkw.com/jxjc/186645/刪除' onclick='del(this)'></div>" } function del(presentNode){ var div=document.getElementById("divId"); div.removeChild(presentNode.parentNode); } </script> <div> 多文件上傳<br/> <form action="/Servlet/upload" method="post" enctype="multipart/form-data"> <input type="button" value="http://www.mnbkw.com/jxjc/186645/添加" onclick="run()"><br/> <div id="divId"></div><input type="submit" value="http://www.mnbkw.com/jxjc/186645/上傳"> </form> </div> </body></html>4. 關于文件上傳的一些問題:
文件重名可能會產生覆蓋效果 , 可以在處理文件名時生成一個唯一的文件名如果所有的文件都儲存在一個文件夾中 , 會導致文件夾下文件過多 , 可以一個用戶一個文件夾 , 或者利用算法目錄分離等方法 。
3. 文件下載
1. 傳統文件下載方式有超鏈接下載或者后臺程序下載兩種方式 。通過超鏈接下載時 , 如果瀏覽器可以解析 , 那么就會直接打開 , 如果不能解析 , 就會彈出下載框;而后臺程序下載就必須通過兩個響應頭和一個文件的輸入流 。
2. 后臺程序下載:
兩個響應頭:Content-Type:其值有比如 text/html;charset=utf-8Content-Disposition:其值為 attachment;filename=文件名 以附件形式打開流:需要獲取文件的輸入流 , 然后通過response對象的輸出流輸出到客戶端 。
import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * @ClassName:DownLoadServlet * @Description:文件下載 * @author:* @date:2018年9月16日 */public class DownLoadServlet extends [email protected] void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {//獲取請求參數 , 知道要下載那個文件String filename=req.getParameter("filename");//設置響應頭String contentType=getServletContext().getMimeType(filename);//依據文件名自動獲取對應的Content-Type頭res.setContentType(contentType);res.setHeader("Content-Dispotition", "attachment;filename="+filename);//設置該頭 , 以附件形式打開下載//獲取文件的輸入流String path=getServletContext().getRealPath("/download")+"/"+filename;FileInputStream in=new FileInputStream(new File(path));OutputStream out= res.getOutputStream();byte[] b=new byte[1024];int len=0;while((len=in.read(b))!=-1){out.write(b,0,len);}in.close();out.close();}}