您好,登錄后才能下訂單哦!
這篇文章主要講解了“java組件SmartUpload和FileUpload怎么實(shí)現(xiàn)文件上傳功能”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“java組件SmartUpload和FileUpload怎么實(shí)現(xiàn)文件上傳功能”吧!
1 SmartUpload上傳組件
SmartUpload上傳組件包,可以輕松的實(shí)現(xiàn)文件的上傳和下載功能;
使用簡(jiǎn)單,實(shí)現(xiàn)上傳文件類型的限制,也可以輕易的取得上傳文件的名稱、后綴、大小等;
SmartUpload本身是系統(tǒng)提供的jar包,將此包考入到lib文件夾中;
此組件的提供方網(wǎng)站已關(guān)閉,SmartUpload在非框架中開發(fā)中較為好用;
上傳單個(gè)文件
要進(jìn)行上傳,必須使用HTML中提供給的file空間,而且<form>必須使用enctype屬性進(jìn)行封裝;
smartupload_demo01.html : 上傳表單
<html> <head><title>上傳表單</title></head> <body> <form action="smartupload_demo01.jsp" method="post" enctype="multipart/form-data"> 請(qǐng)選擇要上傳的文件:<input type="file" name="pic"> <input type="submit" value="上傳"> </form> </body> </html>
在form上使用enctype進(jìn)行了表單封裝,表示表單將按二進(jìn)制的方式提交,即所有的表單此時(shí)不在是分別提交,而是將所有的內(nèi)容都按照二進(jìn)制的方式提交;
smartupload_demo01.jsp : 接收?qǐng)D片,保存在根目錄中的upload文件夾中
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="org.bug.smart.*"%> <html> <head><title>接收?qǐng)D片,保存在根目錄中的upload文件夾中</title></head> <body> <% SmartUpload smart = new SmartUpload() ; smart.initialize(pageContext) ; // 初始化上傳操作 smart.upload() ; // 上傳準(zhǔn)備 smart.save("upload") ; // 文件保存 %> </body> </html>
使用SmartUpload時(shí)必須嚴(yán)格按照如上程序進(jìn)行,最后在保存時(shí)只是寫了一個(gè)upload,表示上傳文件的保存文件夾,此文件要在根目錄中手工建立;
保存的名稱和上傳的文件一樣,所以如果出現(xiàn)相同的文件名稱,將出現(xiàn)覆蓋的情況;
混合表單
當(dāng)一個(gè)表單使用了enctyoe封裝后,其它文件類的表單控件的內(nèi)容將無(wú)法通過(guò)request內(nèi)置對(duì)象取得;
此時(shí),必須通過(guò)SmartUpload類中提供的getRequest()方法取得全部的請(qǐng)求參數(shù);
smartupload_demo02.html ; 混合表單
<html> <head><title>混合表單</title></head> <body> <form action="smartupload_demo02.jsp" method="post" enctype="multipart/form-data"> 姓名:<input type="text" name="uname"><br> 照片:<input type="file" name="pic"><br> <input type="submit" value="上傳"> <input type="reset" value="重置"> </form> </body> </html>
以上表單中包含了文本和文件兩個(gè)控件;
smartupload_demo02.jsp : 接收封裝表單的文本數(shù)據(jù)
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="org.bug.smart.*"%> <%@ page import="cn.com.bug.util.*"%> <html> <head><title>接收封裝表單的文本數(shù)據(jù)</title></head> <body> <% request.setCharacterEncoding("GBK") ; %> <% SmartUpload smart = new SmartUpload() ; smart.initialize(pageContext) ; // 初始化上傳操作 smart.upload() ; // 上傳準(zhǔn)備 String name = smart.getRequest().getParameter("uname") ; smart.upload("upload");%> <h3>姓名:<%=name%></h3> <h3>request無(wú)法取得 : <%=request.getParameter("uname")%> </h3> </body> </html>
表單進(jìn)行了二進(jìn)制封裝,單靠request對(duì)象是無(wú)法取得提交參數(shù)的,必須依靠SmartUpload類中的getRequest().getParameter()方法才能取得請(qǐng)求的參數(shù);
由于是通過(guò)SmartUpload完成參數(shù)接收,所以smart.getRequest()方法一定要在執(zhí)行完upload()方法后才可使用;
為上傳文件自動(dòng)命名
為了解決文件名稱相同而出現(xiàn)覆蓋的情況,可以采用為上傳文件自動(dòng)命名的方式;
自動(dòng)命名可采用格式: IP地址+時(shí)間戳+三位隨機(jī)數(shù)
IPTimeStamp.java : 定義取得IP時(shí)間戳的操作類
package cn.com.bug.util ; import java.text.SimpleDateFormat ; import java.util.Date ; import java.util.Random ; public class IPTimeStamp { private SimpleDateFormat sdf = null ; //定義SimpleDateFormat對(duì)象 private String ip = null ; //接收IP地址 public IPTimeStamp(){ } public IPTimeStamp(String ip){ //得到IP地址+時(shí)間戳+三位隨機(jī)數(shù) this.ip = ip ; } public String getIPTimeRand(){ StringBuffer buf = new StringBuffer() ; //實(shí)例化StringBuffer對(duì)象 if(this.ip != null){ String s[] = this.ip.split("\\.") ; //進(jìn)行拆分操作 for(int i=0;i<s.length;i++){ //循環(huán)設(shè)置IP地址 buf.append(this.addZero(s[i],3)) ; //不夠三位要補(bǔ)0 } } buf.append(this.getTimeStamp()) ; //取得時(shí)間戳 Random r = new Random() ; //定義Random對(duì)象,已產(chǎn)生隨機(jī)數(shù) for(int i=0;i<3;i++){ //循環(huán)三次 buf.append(r.nextInt(10)) ; //增加隨機(jī)數(shù) } return buf.toString() //返回名稱 } public String getDate(){ //取得當(dāng)前系統(tǒng)的時(shí)間 this.sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS") ; return this.sdf.format(new Date()) ; } public String getTimeStamp(){ //取得時(shí)間戳 this.sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS") ; return this.sdf.format(new Date()) ; } private String addZero(String str,int len){ //補(bǔ)0操作 StringBuffer s = new StringBuffer() ; s.append(str) ; while(s.length() < len){ s.insert(0,"0") ; } return s.toString() ; } public static void main(String args[]){ System.out.println(new IPTimeStamp("192.168.1.1").getIPTimeRand()) ; } }
直接修改上傳的操作頁(yè),在上傳的操作頁(yè)中不直接使用save()方法保存;
而是取得一個(gè)具體上傳文件對(duì)象才可以保存,由于上傳文件時(shí)文件的后綴需要統(tǒng)一,所以可以使用getFileExt()方法取得文件的后綴;
smartupload_demo02.jsp : 增加自動(dòng)命名的功能;
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="org.bug.smart.*"%> <%@ page import="cn.com.bug.util.*"%> <html> <head><title>修改后的smartuoload.jsp</title></head> <body> <% request.setCharacterEncoding("GBK") ; %> <% SmartUpload smart = new SmartUpload() ; smart.initialize(pageContext) ; // 初始化上傳操作 smart.upload() ; // 上傳準(zhǔn)備 String name = smart.getRequest().getParameter("uname") ; IPTimeStamp its = new IPTimeStamp(request.getRemoteAddr()) ; // 取得客戶端的IP地址 String ext = smart.getFiles().getFile(0).getFileExt() ; // 擴(kuò)展名稱 String fileName = its.getIPTimeRand() + "." + ext ; smart.getFiles().getFile(0).saveAs(this.getServletContext().getRealPath("/")+"upload"+java.io.File.separator + fileName) ; %> <%=smart.getFiles().getFile(0).getFileName().matches("^\\w+.(jpg|gif)$")%> <h3>姓名:<%=name%></h3> <img src="../upload/<%=fileName%>"> </body> </html>
由于SmartUpload可以同時(shí)接收多個(gè)文件;
此時(shí)通過(guò)smart.getFiles().getFile(0).getFileExt()取得第一個(gè)上傳文件的文件后綴,在與之前IPTimeStampl類生成的文件名稱一起拼湊出一個(gè)新的文件名;
此時(shí)要用的新的文件名稱保存上傳文件,所以要通過(guò)smart.getFiles().getFile(0).saveAs()方法進(jìn)行收工保存;
以上代碼沒(méi)有對(duì)上傳文件的類型進(jìn)行限制,可以通過(guò)正則判斷文件的后綴是否合法;
eg:驗(yàn)證上傳文件的合法性代碼片段
if(smart.getFiles().getFile(0).getFileName().matches("^\\w+\\.(jsp|gif)$")){ //表示只允許后綴為jpg或gif的文件上傳; }
批量上傳
smart.getFiles().getFile(0).saveAs(this.getServletContext().getRealPath("/")+"upload"+java.io.File.separator + fileName) ;
以上證明可以一次性提交多個(gè)上傳文件;
smartupload_demo03.jsp : 編寫表單,上傳3個(gè)文件
<html> <head><title>編寫表單,上傳3個(gè)文件</title></head> <body> <form action="smartupload_demo03.jsp" method="post" enctype="multipart/form-data"> 照片1:<input type="file" name="pic1"><br> 照片2:<input type="file" name="pic2"><br> 照片3:<input type="file" name="pic3"><br> <input type="submit" value="上傳"> <input type="reset" value="重置"> </form> </body> </html>
如果要完成批量上傳,則肯定要使用循環(huán)的方式進(jìn)行,必須通過(guò)以下方式取得上傳文件數(shù)量;
取得上傳文件的數(shù)量:smart.getFiles().getCount();
smartupload_demo03.jsp : 批量上傳
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="org.bug.smart.*"%> <%@ page import="cn.com.bug.util.*"%> <html> <head><title>批量上傳</title></head> <body> <% request.setCharacterEncoding("GBK") ; %> <% SmartUpload smart = new SmartUpload() ; smart.initialize(pageContext) ; // 初始化上傳操作 smart.upload() ; // 上傳準(zhǔn)備 String name = smart.getRequest().getParameter("uname") ; IPTimeStamp its = new IPTimeStamp(request.getRemoteAddr()) ; // 取得客戶端的IP地址 for(int x=0;x<smart.getFiles().getCount();x++){ String ext = smart.getFiles().getFile(x).getFileExt() ; // 擴(kuò)展名稱 String fileName = its.getIPTimeRand() + "." + ext ; smart.getFiles().getFile(x).saveAs(this.getServletContext().getRealPath("/")+"upload"+java.io.File.separator + fileName) ; } %> </body> </html>
2 FileUpload
FileUpload是Apache組織提供的免費(fèi)上傳組件,可以直接從站點(diǎn)進(jìn)行下載;
FileUpload組件本身依賴于Commons組件包,所以從Apache下載此組件的同時(shí)連同Commons組件的IO包一起下載(http://commons.apache.org/io);
Commons組件包在很多框架開發(fā)中都可以直接使用,此包中提供了大量開發(fā)類可作為java的有力補(bǔ)充;
將Commons-fileupload-1.2.1.jar和Common-io-1.4.jar配置到lib文件夾中;
使用FileUpload接收上傳內(nèi)容
不論是使用SmartUpload和FileUpload進(jìn)行上傳操作,都是依靠HTML的file控件完成的;
fileupload_demo01.html : 上傳表單
<html> <head><title>上傳表單</title></head> <body> <form action="fileupload_demo01.jsp" method="post" enctype="multipart/form-data"> 姓名:<input type="text" name="uname"><br> 照片:<input type="file" name="pic"><br> <input type="submit" value="上傳"> <input type="reset" value="重置"> </form> </body> </html>
FileUpload的具體上傳操作與SmartUpload相比有著很高的復(fù)雜度;
以下是FileUpload上傳的步驟:
1 創(chuàng)建磁盤工廠:DiskFileItemFactory factory = new DiskFileFactory();
2 創(chuàng)建處理工具:ServletFileUpload upload =new ServletFileUpload(factory);
3 設(shè)置文件的上傳大小:upload.setFileSizeMax(3145728);
4 接收全部的內(nèi)容:List<FileItem> items = upload.parseRequest(request);
FileUpload對(duì)所有的上傳內(nèi)容都采用同樣的方式操作;
與SmartUpload不同的是,會(huì)將所有的上傳內(nèi)容一起(包括文件和普通參數(shù))接收;
所以需要依次判斷你每一次上傳的內(nèi)容是文件還是普通文本;
fileupload_demo01.jsp : 接收上傳文件
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="java.util.*"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.fileupload.disk.*"%> <%@ page import="org.apache.commons.fileupload.servlet.*"%> <html> <head><title>接收上傳文件</title></head> <body> <% DiskFileItemFactory factory = new DiskFileItemFactory() ; ServletFileUpload upload = new ServletFileUpload(factory) ; upload.setFileSizeMax(3 * 1024 * 1024) ; // 只能上傳3M List<FileItem> items = upload.parseRequest(request) ; // 接收全部?jī)?nèi)容 Iterator<FileItem> iter = items.iterator() ;//將全部的內(nèi)容變?yōu)镮terator實(shí)例 while(iter.hasNext()){ //依次取出每一個(gè)內(nèi)容 FileItem item = iter.next() ; //取出每一個(gè)上傳的文件 String fieldName = item.getFieldName() ; // 取得表單控件的名稱 %> <ul><h5><%=fieldName%> --> <%=item.isFormField()%></h5> <% if(!item.isFormField()){ // 不是普通文本 String fileName = item.getName() ; // 取得文件的名稱 String contentType = item.getContentType() ; // 文件類型 long sizeInBytes = item.getSize() ;//文件大小 %> <li>上傳文件名稱:<%=fileName%> <li>上傳文件類型:<%=contentType%> <li>上傳文件大小:<%=sizeInBytes%> <% } else { String value = item.getString() ; %> <li>普通參數(shù):<%=value%> <% } %> </ul> <% } %> </body> </html>
FileUpload組件接收完全部的數(shù)據(jù)后,所有的數(shù)據(jù)都保存在List集合中,則需要使用Iterator取出每一個(gè)數(shù)據(jù);
但是由于其中既有普通的文本數(shù)據(jù)又有上傳的文件,每一個(gè)上傳內(nèi)容都使用一個(gè)FileItem類對(duì)象表示;
所以當(dāng)使用Iterator依次取出每一個(gè)FileItem對(duì)象時(shí),就可以使用FileItem類中的isFormField()方法來(lái)判斷當(dāng)前操作的內(nèi)容是普通的文本還是附件上傳;
如果是上傳文件,則將文件的內(nèi)容依次取出;如果是普通的文本,則直接通過(guò)getString()方法取得具體的信息;
保存上傳內(nèi)容
以上完成了接收上傳文件內(nèi)容的操作,但是所上傳的文件現(xiàn)在并沒(méi)有真正的保存在服務(wù)器上;
而要進(jìn)行文件的保存,在FileUpload中就必須通過(guò)java.io包中InputStream和outputStream兩個(gè)類完成文件的自動(dòng)命名操作;
InputStream和OutputStream為兩個(gè)抽象類,必須依靠FileInputStream和OutputStream類進(jìn)行對(duì)象的實(shí)例化操作;
fileupload_demo02.html : 定義上傳表單,可以同時(shí)上傳多個(gè)文件
<html> <head><title>定義表單,可以同時(shí)上傳多個(gè)文件</title></head> <body> <form action="fileupload_demo02.jsp" method="post" enctype="multipart/form-data"> 姓名:<input type="text" name="uname"><br> 照片:<input type="file" name="pic1"><br> 照片:<input type="file" name="pic2"><br> 照片:<input type="file" name="pic3"><br> <input type="submit" value="上傳"> <input type="reset" value="重置"> </form> </body> </html>
fileupload_demo02.jsp : 保存上傳的內(nèi)容
<%@ page contentType="text/html" pageEncoding="GBK"%> <%@ page import="java.util.*,java.io.*"%> <%@ page import="org.apache.commons.fileupload.*"%> <%@ page import="org.apache.commons.fileupload.disk.*"%> <%@ page import="org.apache.commons.fileupload.servlet.*"%> <%@ page import="cn.com.bug.util.*"%> <html> <head><title>保存上傳內(nèi)容</title></head> <body> <% DiskFileItemFactory factory = new DiskFileItemFactory() ; factory.setRepository(new File(this.getServletContext().getRealPath("/") + "uploadtemp")) ; // 設(shè)置一個(gè)臨時(shí)文件 ServletFileUpload upload = new ServletFileUpload(factory) ; upload.setFileSizeMax(3 * 1024 * 1024) ; // 只能上傳3M List<FileItem> items = upload.parseRequest(request) ; // 接收全部?jī)?nèi)容 Iterator<FileItem> iter = items.iterator() ; //將全部的內(nèi)容轉(zhuǎn)換為Iterator實(shí)例 IPTimeStamp its = new IPTimeStamp(request.getRemoteAddr()) ;//實(shí)例化IP時(shí)間戳對(duì)象 while(iter.hasNext()){//依次取出每一個(gè)內(nèi)容 FileItem item = iter.next() ; //取出每一個(gè)上傳的文件 String fieldName = item.getFieldName() ; // 取得表單控件的名稱 %> <ul><h5><%=fieldName%> --> <%=item.isFormField()%></h5> <% if(!item.isFormField()){ // 不是普通文本,是上傳文件 File saveFile = null ; //定義保存的文件 InputStream input = null ; OutputStream output = null ; input = item.getInputStream() ; output = new FileOutputStream(new File(this.getServletContext().getRealPath("/")+"upload"+File.separator+its.getIPTimeRand()+ "."+item.getName().split("\\.")[1])) ;//定義輸入文件的路徑 int temp = 0 ; byte data[] = new byte[512] ; while((temp=input.read(data,0,512))!=-1){ //依次讀取內(nèi)容 output.write(data) ; // 分塊保存 } input.close() ; output.close() ; } else { String value = item.getString() ;//取出表單的內(nèi)容 %> <li>普通參數(shù):<%=value%> <% } %> </ul> <% } %> </body> </html>
以上代碼中,首先會(huì)將所有的上傳文件設(shè)置到臨時(shí)文件夾中;
如果發(fā)現(xiàn)取得的表單是上傳文件,則使用InputStream,從FileItem類中取得文件的輸入流;
在使用OutputStream將內(nèi)容依次取出,保存在具體的文件路徑中;
FileUpload在建的不便之處:
1 無(wú)法像使用request.getParameter()方法那樣準(zhǔn)確地取得提交的參數(shù);
2 無(wú)法像使用request.getParameterValues()那樣準(zhǔn)確的取得一組提交參數(shù);
3 所有的上傳文件度需要進(jìn)行一次的判斷,才能夠分別保存,不能一次性批量保存;
感謝各位的閱讀,以上就是“java組件SmartUpload和FileUpload怎么實(shí)現(xiàn)文件上傳功能”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)java組件SmartUpload和FileUpload怎么實(shí)現(xiàn)文件上傳功能這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。