日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

18-文件上传

發(fā)布時(shí)間:2024/9/27 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 18-文件上传 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、文件上傳入門(mén)

1. 應(yīng)用:

?用戶上傳頭像、上傳圖片、郵件上傳附件等

2. 頁(yè)面表單的實(shí)現(xiàn)

??? 文件上傳表單和普通表單有兩個(gè)區(qū)別

??? 1) 需要文件上傳字段? <input type=”file” />

??? 2) form 表單的 enctype 屬性需要指定為 multipart/form-data

3. 服務(wù)器端解析request

??? 在 Servlet 中通過(guò) request.getInputStream 獲得表單上傳數(shù)據(jù),會(huì)發(fā)現(xiàn)數(shù)據(jù)是分段發(fā)送的

由于自己寫(xiě)程序解析有難度,我們可以使用Apache 開(kāi)發(fā)的開(kāi)源組件Commons-fileupload

需要導(dǎo)入 jar 包Commons-fileupload 和Commons-io

4 . UploadServlet 中處理文件上傳程序

?

// 1. 創(chuàng)建工廠類(lèi)

DiskFileItemFactory factory = new DiskFileItemFactory();

// 2. 創(chuàng)建FileUpload對(duì)象

ServletFileUpload upload = new ServletFileUpload(factory);

// 3. 判斷是否是上傳表單

boolean b = upload.isMultipartContent(request);

if(!b) {

??? // 不是文件上傳

request.setAttribute("message", "對(duì)不起,不是文件上傳表單!");

request.getRequestDispatcher("/message.jsp").forward(request, response);

??? return;

}

// 是文件上傳表單

// 4. 解析request,獲得FileItem項(xiàng)

List<FileItem> fileitems = upload.parseRequest(request);

// 5. 遍歷集合

for(FileItem item : fileitems) {

??? // 判斷是不是普通字段

if(item.isFormField()) {

??? String name = item.getFieldName();

??? String value = item.getString();

??? // 手工的轉(zhuǎn)換了

??? value = new String(value.getBytes("iso-8859-1"),"utf-8");

??? System.out.println(name + "=" + value);

} else {

??? // 文件上傳字段

??? // 獲得文件名

??? String filename = item.getName();

??? System.out.println(filename);

??? filename = filename.substring(filename.lastIndexOf("\\")+1);

???

??? System.out.println(filename);

??? // 創(chuàng)建文件

??? ServletContext context = getServletContext();

??? String dir = context.getRealPath("WEN-INF/upload");

??? File file = new File(dir, filename);

??? file.createNewFile();

???

??? // 獲得流,讀取數(shù)據(jù)寫(xiě)入文件

??? InputStream in = item.getInputStream();

??? FileOutputStream fos = new FileOutputStream(file);

???

??? int len;

??? byte[] buffer = new byte[1024];

??? while((len=in.read(buffer))>0)

?????? fos.write(buffer,0,len);

??? fos.close();

??? in.close();

??? item.delete();??? // 刪除臨時(shí)文件

}

?

?

二、 文件上傳處理細(xì)節(jié)

1. 中文亂碼問(wèn)題

??? 1) 文件名中文亂碼問(wèn)題,解決辦法: 告訴文件上傳組件以什么編碼方式來(lái)解碼文件名

?????? ServletUpload.setCharacterEncoding(“utf-8”);

?????? request. setCharacterEncoding(“utf-8”);

????

??? 2) 普通字段中文亂碼問(wèn)題

?????? fileitem.getString(“utf-8”);??????

?

2. ? 臨時(shí)文件

??? 對(duì)于大文件不能緩存在內(nèi)存,需要緩存到硬盤(pán),為了方便管理,我們需要設(shè)置臨時(shí)文件存放目錄

??? // 設(shè)置臨時(shí)文件的存放位置

factory.setRepository(new File("d:/temp"));

?

??? 文件上傳完畢需要?jiǎng)h除臨時(shí)文件,否則會(huì)導(dǎo)致服務(wù)器存在兩份上傳文件

// 注意,需要先將流進(jìn)行關(guān)閉,否則會(huì)導(dǎo)致臨時(shí)文件無(wú)法刪除

out.close();

in.close();

// 刪除臨時(shí)文件

fileitem.delete();

?

3. 文件存放目錄

??? 1) 目錄需要隱藏,禁止外界直接訪問(wèn)

??? 2) 文件名需要保證不重復(fù)

??? 3) 文件應(yīng)該分目錄存放

?

三、上傳進(jìn)度條

1. 實(shí)現(xiàn)進(jìn)度監(jiān)聽(tīng)

??? 需要實(shí)現(xiàn)對(duì)文件上傳進(jìn)度的監(jiān)聽(tīng),需要給FileUpload 對(duì)象添加 ProgressListener

??? 在upload方法中對(duì)與進(jìn)度相關(guān)的數(shù)據(jù)進(jìn)行處理

??? upload.setProgressListener(new ProgressListener() {

??? long num = 0;

??? public void update(long bytesRead, long contentLength, int items) {

??????

??? ??? ??? long progress = bytesRead*100/contentLength;

?????? ??? if(progress==num)

?????????? ??? return;

?????? ??? num = progress;

?????? ??? System.out.println("上傳進(jìn)度:" + progress + "%");

??????

??? ??? //? request.getSession().setAttribute("progress", progress);

??? ??? }

??? });

?

2. jsp 頁(yè)面顯示進(jìn)度

??? 實(shí)驗(yàn):?

??? 1) 使用 iframe 發(fā)送請(qǐng)求, 請(qǐng)求一個(gè)Servlet, 在Servlet 中返回響應(yīng),發(fā)送自增的num

?????? 此時(shí)會(huì)發(fā)現(xiàn) iframe 會(huì)不停第想Servlet發(fā)送請(qǐng)求

??? 2) 點(diǎn)擊文件上傳按鈕后,iframe立刻停止刷新,直至上傳完畢頁(yè)面跳轉(zhuǎn)至新頁(yè)面

??? 3)為了觀察實(shí)驗(yàn)結(jié)果,將form 的 target 指定為 iframe, UploadServlet回送上傳完畢的結(jié)果

??? 4) 出現(xiàn)上述問(wèn)題的原因,瀏覽器不支持多線程同時(shí)訪問(wèn)服務(wù)器只能同時(shí)發(fā)送一個(gè)請(qǐng)求,

?????? 這樣的訪問(wèn)方式為同步訪問(wèn)

??? 5) 要在文件上傳的同時(shí)在iframe中實(shí)現(xiàn)進(jìn)度訪問(wèn),就需要ie瀏覽器與服務(wù)器進(jìn)行異步交互

?????? 此時(shí)就需要 XMLHttpRequest 對(duì)象

?????? 在javascript中可以直接使用XMLHttpRequest 對(duì)象與服務(wù)器進(jìn)行異步通信

?????? 獲得XmlHttpRequest 對(duì)象的方式有兩種

?????? ie7以上版本

?????? var xhr = null;

?????? if(window.XMLHttpRequest)

?????????? xhr = new XMLHttpRequest();

?????? ie7以下版本

?????? if(window.ActiveXObject)

?????????? xhr = new ActiveXObject(“Microsoft.XMLHTTP”);

??????

?????? 獲得對(duì)象后需要調(diào)用open方法輸入請(qǐng)求地址

?????? 注意請(qǐng)求方式, 地址的輸入, 并且需要設(shè)置為true 指定異步訪問(wèn)該地址

?????? xhr.open(“get”,”/upload/servlet/UploadServlet”, false)

??????

?????? // 調(diào)用send 方法發(fā)送請(qǐng)求,post方式需要發(fā)送消息體,get方式則不用直接傳入null值

?????? xhr.send(null);

??????

?????? // 訪問(wèn) responseText 屬性獲得 Servlet 回送的數(shù)據(jù)

?????? document.write(xhr.responseText);

?

四、 api方法

1. DiskFileItemFactory 對(duì)象

??? 設(shè)置緩沖區(qū)大小,字節(jié)為單位,默認(rèn)為10K,一般不用修改

??? factory.setSizeThreshold(1000);

??? 設(shè)置臨時(shí)文件存放目錄

??? factory.setRepository(file);

?

2. ServletFileUpload 對(duì)象

??? 判斷是否為文件上傳表單

??? boolean b = upload.isMultipartContent(request);

?? 解析request對(duì)象

?? List<FileItem> list = upload.parseRequest(request);

?? 設(shè)置上傳文件的最大值

??? setFileSizeMax(long?fileSizeMax)

??? 設(shè)置上傳文件總量的最大值

??? setSizeMax(long?sizeMax)

??? 設(shè)置編碼格式

??? setHeaderEncoding(java.lang.String?encoding)

??? 注冊(cè)進(jìn)度監(jiān)聽(tīng)器

??? setProgressListener(ProgressListener?pListener)

?

3. FileItem 對(duì)象

??? 獲得表單字段的屬性名

??? item.getFieldName();

??? 獲得普通字段的值

??? item.getString(charsetName)

??? 獲得文件上傳字段的文件名

??? item.getName()

??? 獲得文件上傳的流

??? item.getInputStream()

??

?

總結(jié)

以上是生活随笔為你收集整理的18-文件上传的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。