**文件上傳的概述** 1.瞭解什麼是文件上傳 2.文件上傳須要你們記住編寫客戶端須要有3個注意事項。 3.什麼是文件上傳 * 把本地的文件保存到服務器端 4.作文件上傳,該怎麼作? * 客戶端 * 選擇一個要上傳的文件 * 須要提供文件的選擇輸入框(<input type="file">) * 注意:若是完成文件的上傳,必須有3點注意事項的 * 編寫表單,method="post" 必須是post * 表單中還有一個屬性,enctype="multipart/form-data" * 編寫文件的選項框 <input type="file" name="必需要指定,名稱能夠任意"> * 服務器端 * 把上傳的文件寫入到某個指定的文件夾下  ---------- **Fileupload文件上傳的組件** 1.由apache提供的開源的jar包 * 導入開發的jar包 * commons-fileupload-1.2.1.jar * commons-io-1.4.jar 2.入門的開發 * 開發的步驟,開發的步驟比較固定  ---------- **文件上傳入門案例** 1.編寫入門的案例,目的:讓你們來熟悉開發的步驟,使用一些對象和方法,後面講解。 2.文件上傳的案例步驟 * 客戶端 * 注意3個注意事項 * 服務器端 * 採用的是FileUpload文件上傳的組件,不要忘記導入開發的jar包。 * 建立工廠類,生成對象 * 建立核心解析類,解析request請求,獲取到文件項(FileItem) * 操做FileItem類的方法就能夠完成文件的上傳了 ---------- ### FileUpload組件的類和方法 ### ---------- **DiskFileItemFactory類** 1.DiskFileItemFactory:表明磁盤文件項工廠類,做用:用來生產FileItem對象的。 2.方法 * DiskFileItemFactory() -- 空的構造常常使用的。 * DiskFileItemFactory(int sizeThreshold, java.io.File repository) * sizeThreshold -- 設置上傳文件的緩衝區的大小,若是不指定,有默認值是10K * repository -- 設置臨時文件的存儲目錄,若是上傳的文件,超過了緩衝區的大小,產生臨時文件,設置臨時文件存儲的目錄。 * void setSizeThreshold(int sizeThreshold) -- 設置緩衝區的大小 * void setRepository(java.io.File repository) -- 設置臨時文件的存儲目錄(上傳的文件超過了緩衝區的大小,產生臨時文件) 3.總結 * 上述的這兩個方法,若是不設置都有默認值的。 ---------- **ServletFileUpload類(解析request)** 1.ServletFileUplod 表明的文件上傳的類,做用:用來解析request請求。 2.方法 * ServletFileUpload(FileItemFactory fileItemFactory) * static boolean isMultipartContent(javax.servlet.http.HttpServletRequest request) -- 判斷表單的enctype值設置的是否正確 * java.util.List parseRequest(javax.servlet.http.HttpServletRequest request) -- 解析request請求,返回的是List集合 * void setHeaderEncoding(java.lang.String encoding) -- 解決中文文件名稱亂碼的問題。 * void setFileSizeMax(long fileSizeMax) -- 設置單個上傳文件的大小 * void setSizeMax(long sizeMax) -- 設置總大小 3.總結(掌握) * parseRequest(request) -- 解析request請求 * setHeaderEncoding() -- 解決中文亂碼問題呢 * setSizeMax() -- 設置上傳文件的總大小 * void setFileSizeMax() ---------- **FileItem接口(文件項)** 1.FileItem類:表明文件項(普通表單項(文本框、密碼、單選),又有可能文件的上傳項) 2.方法 * boolean isFormField() * 判斷當前的fileItem對象是不是普通表單項仍是文件上傳項?若是返回true,說明是普通表單項,若是是false,是文件上傳項 * 若是是普通表單項(文本框 密碼框 複選框 單選框 下拉列表) * java.lang.String getFieldName() -- 獲取的表單中的name屬性的值(例如:filedesc) * java.lang.String getString() -- 獲取到用戶輸入的值(沒有解決亂碼的問題) * java.lang.String getString(String encoding) -- 獲取到用戶輸入的值(解決中文亂碼問題) * 若是是文件上傳項 * java.lang.String getName() -- 獲取的上傳文件的名稱(ServletFileUpload類中setHeaderEncoding()解決中文亂碼) * java.io.InputStream getInputStream() -- 獲取到上傳文件的輸入流 * void write(java.io.File file) -- 直接寫入文件 * void delete() -- 刪除臨時文件的(注意:刪除的代碼須要放在流關閉以後) 3.總結 * 上述全部 ---------- **文件上傳存在的問題** 1.第一個問題:若是使用的是IE6瀏覽器,存在問題。 * 若是是IE6的瀏覽器,獲取的文件的名稱是:C:\class\resource\hello.txt * 若是瀏覽器是IE的一些版本(IE6確定存在該問題),若是使用的是IE6版本的瀏覽器,選擇文件的時候,選擇完文件,點擊上傳。 * 在Servlet中獲取到的文件名稱是包含文件的路徑的。 2.第二個問題:request.getParameter()方法已經不能獲取到表單的內容了。(重要的) * 使用request對象的時候,request.getParameter()方法,在文件上傳中,使用的enctype="multipart/form-data"方式,那麼request.getParameter()獲取不到值了。 3,注意; request.getParameter()已經不能獲取到值了!!!
upload.jsp:javascript
<%@ 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> <h3>文件的上傳</h3> <form action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data"> 文件描述:<input type="text" name="filedesc"/><br/> 文件上傳:<input type="file" name="upload"/><br/> <input type="submit" value="上傳"/> </form> </body> </html>
UploadServlet:html
public class UploadServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * 1.建立一個工廠類 * 2.建立能解析request對象的類 * 3.解析request請求 * 4.返回的是List集合 * 5.遍歷集合,獲取到每個FileItem * 6.操做FileItem中方法完成文件的上傳 */ //判斷,表單的enctype屬性值是否設置正確,返回true,說明設置正確。返回false,不正確 if(!ServletFileUpload.isMultipartContent(request)){ //說明設置不正確 throw new RuntimeException("親,您沒有設置正確的enctype屬性的值"); } //1.建立工廠類 DiskFileItemFactory factory=new DiskFileItemFactory(); //設置緩衝區的大小 設置2M factory.setSizeThreshold(2*1024*1024); //設置臨時文件的存儲目錄 String tempPath=this.getServletContext().getRealPath("/temp"); System.out.println(tempPath); //建立文件目錄 File tempFile=new File(tempPath); factory.setRepository(tempFile); //2.建立能解析request對象的類 ServletFileUpload upload=new ServletFileUpload(factory); //設置頭的編碼,解決中文文件名稱亂碼的問題 upload.setHeaderEncoding("utf-8"); //設置文件上傳的總大小 4M upload.setSizeMax(4*1024*1024); try { //3.解析request請求 //4.返回的是List集合 List<FileItem> list=upload.parseRequest(request); //5.遍歷集合,獲取到每個FileItem for (FileItem fileItem : list) { //須要判斷,當前的fileItem是不是文件描述仍是文件上傳 //isFormField(),返回true,說明表單的字段(text,password,checkbox,radio) if(fileItem.isFormField()){ //獲取表單中name屬性的值 String name=fileItem.getFieldName(); //文件描述,獲取用戶輸入的值 String value= fileItem.getString(); String value_=fileItem.getString("UTF-8"); System.out.println(name+":::"+value+value_); }else{ //返回false,說明type="file" 說明是文件上傳,須要獲取用戶上傳的文件的文件名稱 String fileName=fileItem.getName(); //生成惟一的文件的名稱 String uuid=UUID.randomUUID().toString(); //名稱徹底換掉hello.txt --> ffggerwefd.txt int i=fileName.lastIndexOf("."); //文件的後綴名 String lastName=fileName.substring(i); String uuidName=uuid+"_"+lastName; //獲取到的是文件的輸入流 InputStream in=fileItem.getInputStream(); //獲取upload文件夾的絕對路徑 String path=this.getServletContext().getRealPath("/upload"); System.out.println("upload文件夾的絕對路徑:"+path); //建立輸出流 OutputStream out=new FileOutputStream(path+"/"+uuidName); byte[] by=new byte[1024]; int len=0; while((len=in.read(by))!=-1){ out.write(by, 0 ,len); } out.close(); in.close(); } } } catch (FileUploadException e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
**多文件上傳(js控制多個上傳輸入項)** 1.多文件上傳 * 需求:點擊添加按鈕,生成多個文件的上傳項。點擊刪除的按鈕,刪除該個上傳項。點擊上傳按鈕,把選擇的全部的文件上傳到服務器端。 * 前臺和後臺
moreupload.jsp:java
<%@ 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> <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.js"></script> <script type="text/javascript"> $(function(){ $("input[type='button']").click(function(){ //建立div var $div=$("<div></div>"); //建立選擇框 var $input=$("<input type='file' name='upload'/>"); var $del=$("<input type='button' value='刪除'/><br/>"); //給刪除按鈕綁定事件 $del.click(function(){ //刪除一行,小div $(this).parent().remove(); }); $div.append($input); $div.append($del); //生成的小div存入大的div $("#divId").append($div); }); }); </script> </head> <body> <h3>多文件的上傳</h3> <form action="${pageContext.request.contextPath }/upload" method="post" enctype="multipart/form-data"> <input type="button" value="添加" /> <input type="submit" value="上傳"/> <!-- div,存放生成文件的選擇項 --> <div id="divId"></div> </form> </body> </html>
案例:上傳圖書封面jquery
AddServlet:apache
/** * 添加商品(包含文件的上傳) * @author mjl * */ public class AddProduct extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { DiskFileItemFactory factory=new DiskFileItemFactory(); ServletFileUpload upload=new ServletFileUpload(factory); //解決中文文件名稱亂碼問題 upload.setHeaderEncoding("utf-8"); //建立一個Map,存入用戶輸入的值 Map<String,String> map=new HashMap(); Product product=new Product(); String uuidName=null; try { List<FileItem> list = upload.parseRequest(request); for (FileItem fileItem : list) { if(fileItem.isFormField()){ //獲取到每一個表單項的name的值 String name=fileItem.getFieldName(); //獲取到用戶輸入的值 String value=fileItem.getString("utf-8"); //存入到map集合 map: pname 故事會 price 10 map.put(name, value); }else{ String fileName=fileItem.getName(); if(fileName!=null && !fileName.trim().isEmpty()){ String uuid=MyUUIDUtils.getUUID(); int i=fileName.lastIndexOf("."); String lastName=fileName.substring(i); //惟一的文件名稱 uuidName=uuid+lastName; InputStream in=fileItem.getInputStream(); String path=this.getServletContext().getRealPath("/bookcover"); System.out.println(path); OutputStream out=new FileOutputStream(path+"/"+uuidName); int len=0; byte[] by=new byte[1024]; while((len=in.read(by))!=-1){ out.write(by, 0, len); } out.close(); in.close(); fileItem.delete(); } } } //使用BeanUtils來封裝數據 BeanUtils.populate(product, map); product.setImgUrl(uuidName); ProductService ps=new ProductService(); ps.save(product); //若是添加成功了,跳轉查詢全部商品的方法 response.sendRedirect(request.getContextPath()+"/product?method=findAll"); } catch (Exception e) { e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
文件下載:瀏覽器
download.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>Insert title here</title> </head> <body> <h3>文件下載的頁面</h3> <h4><a href="${pageContext.request.contextPath }/download?filename=大二.jpg">大二.jpg</a></h4> <h4><a href="${pageContext.request.contextPath }/download?filename=guoguo.jpg">guoguo.jpg</a></h4> <h4><a href="${pageContext.request.contextPath }/download?filename=wangwang.txt">wangwang.txt</a></h4> </body> </html>
DownloadServlet:app
/** * 文件的下載 * @author mjl * */ public class DownloadServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //先獲取文件的名稱 String filename=request.getParameter("filename"); //兩個頭(響應頭),一個流(文件的輸入流) //content-Type 表明要下載文件的MIME的類型 txt=text/plain jpg=image/jpeg //response.senContentType("text/html;charset=utf-8"); String mimeType=getServletContext().getMimeType(filename); System.out.println("文件的MIME類型:"+mimeType); response.setContentType(mimeType); //彈出下載的窗口 Content-Disposition 值 attachment;filenmae=加上文件名稱 response.setHeader("Content-Disposition", "attachment;filename="+filename); //獲取download的路徑 String path=this.getServletContext().getRealPath("/download"); InputStream in=new FileInputStream(path+"/"+filename); //使用response對象,響應 OutputStream out=response.getOutputStream(); byte[] by=new byte[1024]; int len=0; while((len=in.read(by))!=-1){ out.write(by,0,len); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }