<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    MDA/MDD/TDD/DDD/DDDDDDD
    posts - 536, comments - 111, trackbacks - 0, articles - 0
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    使用commons fileupload的零碎筆記

    Posted on 2007-08-27 11:58 leekiang 閱讀(30341) 評論(6)  編輯  收藏 所屬分類: fileupload
    我對表單上傳的理解(可能有誤):
    ?<form action="" method="post" enctype="multipart/form-data">
    ?最大上傳2G.
    通過 http 協議上傳文件(rfc1867協議概述,jsp 應用舉例,客戶端發送內容構造)
    ?服務器接收到上傳的流,自己其實是不作任何處理的,那個request還是原裝的,誰來處理這個request呢,一般采用第三方的工具,這里以commons fileupload為例.
    ?
    DiskFileItemFactory?factory?=?new?DiskFileItemFactory();
    factory.setSizeThreshold(
    4096);//?設置緩沖,這個值決定了是fileinputstream還是bytearrayinputstream
    factory.setRepository(new File("d:\\temp"));//設置臨時存放目錄,默認是new File(System.getProperty("java.io.tmpdir"))
    ServletFileUpload?sfu?=?new?ServletFileUpload(factory);
    sfu.setSizeMax(
    100*1024*1024);//100M
    List items?=?sfu.parseRequest(request);//傳入的這個request還是原裝的
    ?見上面的代碼,commons fielupload通過ServletFileUpload類的parseRequest(request)方法處理這個原始流。而ServletFileUpload又會調用其爺爺類FileUploadBase的parseRequest(request)方法,然后又會調return parseRequest(new ServletRequestContext(request)),代碼如下

    ????????
    try?{
    ????????????FileItemIterator?iter?
    =?getItemIterator(ctx);
    ????????????List?items?
    =?new?ArrayList();
    ????????????FileItemFactory?fac?
    =?getFileItemFactory();
    ????????????
    if?(fac?==?null)?{
    ????????????????
    throw?new?NullPointerException(
    ????????????????????
    "No?FileItemFactory?has?been?set.");
    ????????????}
    ????????????
    while?(iter.hasNext())?{
    ????????????????FileItemStream?item?
    =?iter.next();
    ????????????????FileItem?fileItem?
    =?fac.createItem(item.getFieldName(),
    ????????????????????????item.getContentType(),?item.isFormField(),
    ????????????????????????item.getName());
    ????????????????
    try?{
    ????????????????????Streams.copy(item.openStream(),?fileItem.getOutputStream(),
    ????????????????????????????
    true);
    ????????????????}?
    catch?(FileUploadIOException?e)?{
    ????????????????????
    throw?(FileUploadException)?e.getCause();
    ????????????????}?
    catch?(IOException?e)?{
    ????????????????????
    throw?new?IOFileUploadException(//報錯經常在這里
    ????????????????????????????
    "Processing?of?"?+?MULTIPART_FORM_DATA
    ????????????????????????????
    +?"?request?failed.?"?+?e.getMessage(),?e);
    ????????????????}
    ????????????????
    if?(fileItem?instanceof?FileItemHeadersSupport)?{
    ????????????????????
    final?FileItemHeaders?fih?=?item.getHeaders();
    ????????????????????((FileItemHeadersSupport)?fileItem).setHeaders(fih);
    ????????????????}
    ????????????????items.add(fileItem);
    ????????????}
    ????????????
    return?items;
    ????????}?
    catch?(FileUploadIOException?e)?{
    ????????????
    throw?(FileUploadException)?e.getCause();
    ????????}?
    catch?(IOException?e)?{
    ????????????
    throw?new?FileUploadException(e.getMessage(),?e);
    ????????}
    ????

    ?這里注意,上傳的<input type=file
    >標記一定要有name,如果沒有,commons fielupload不作處理
    ?commons fielupload會把上傳的文件以流的方式寫入到temp文件夾,臨時文件夾可以自己設定,如果不手動設置,則是Servlet容器為web應用分配的臨時目錄,tomcat可能就是%TOMCAT_HOME%\temp,我用weblogic時,是C:\DOCUME~1\yourname\LOCALS~1\Temp\。這些臨時文件以"upload"開頭,格式是.tmp,例如"upload_47fdc3_11c9eb678b0__8000_00000043.tmp"
    ?在上傳過程中commons fielupload才知道上傳的文件的大小,如果你定義允許的最大附件為100M,然后你上傳一個200M的文件,那么只有實際傳輸了100M以后,commons fielupload才知道超過了,然后拋出一個異常(org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException)。
    ?commons fielupload處理完了以后(處理過程全在parseRequest(request)方法里),返回一個List,里面的每一項已被封裝為FileItem,你通過fileItem.isFormField()判斷出是普通的表單屬性呢,還是一個文件,如果是文件,你可以從fileItem.getInputStream()獲得輸入流,這個輸入流其實是一個FileInputStream.當然,如果文件很小,則是ByteArrayInputStream.那么如何區分?這兩者的區別是由factory.setSizeThreshold(4096)確定的。大于4K,為FileInputStream,小于4K為ByteArrayInputStream

    這樣就可以解釋struts用ActionForm的方式處理上傳附件的一些問題了,struts接收到enctype="multipart/form-data"的post請求后,會看那個對應的action有沒有配置actionform,如果配置了,就會作一些處理,所以你在action里得到的request已經不是一個普通的request了,而是一個被封裝過的request。如果想得到原始的request,就不要struts-config.xml里給action類配置actionform

    tempDir指定的目錄中可能會隨著時間推移出現很多后綴為"tmp"的垃圾文件,commons-fileupload1.2提供了一個不錯的解決方法,就是把下面的代碼加入到web.xml中即可。
    <listener>
    <listener-class>
    org.apache.commons.fileupload.servlet.FileCleanerCleanup
    </listener-class>
    </listener>
    來源:http://fratemity1314.spaces.live.com/Blog/cns!E3BCC13A1E72BB4F!222.entry

    Q:I'm using FileUpload in an Action, but it's not working. Why?

    A:Struts recognises multipart requests, and parses them automatically, presenting the request parameters to your code in the same manner as if they were regular request parameters. Since struts has already processed the request, and made it available in your form bean, the input stream is no longer available for parsing, so attempting to do so with FileUpload will fail.

    Q:But I need to parse the request myself. How can I do that?

    A:Struts parses multipart a request as a part of the process of populating your form bean from that request. If, for some reason, you need to have full control over the multipart parsing, you can do so by configuring your action mapping without an associated form bean. (A better way of doing this, however, is to replace the default multipart handler with your own. See the struts documentation for details.)



    1,直接用commons fileupload而不用struts的ActionForm時,表單里的屬性值不能用request.getParameter()獲取了,而url里的queryString可以。
    2,? 獲取form里的屬性值的代碼


    ????????????????????String?formname?
    =?fi.getFieldName();//?獲取form中的名字
    ????????????????????String?formcontent?=?fi.getString();
    ????????????????????
    if?(formname.equals("id"))?{
    ????????????????????????id?
    =?formcontent;
    ????????????????????}
    ?else?if?(formname.equals("title"))?{
    ????????????????????????title?
    =?formcontent;
    ????????????????????}
    ?else?if?(formname.equals("memo"))?{
    ????????????????????????memo?
    =?formcontent;
    ????????????????????}

    ????????????????

    3, 表單里的file控件的name不能為空。
    4,上傳大文件(190多M)時報異常
    org.apache.commons.fileupload.FileUploadException: ? Processing ? of ? multipart/form-data ? request ? failed. ? EOF ? after ? reading ? only: ? "3567789 " ? of: ? "203323339 " ? promised ? bytes, ? out? of ? which ? at ? least: ? "0 " ? were ? already ? buffered
    http://forums.bea.com/thread.jspa?threadID=200033356
    http://dev2dev.bea.com.cn/bbs/thread.jspa?forumID=121&threadID=20060&start=0&tstart=0
    http://thisisxy.blogcn.com/diary,204014352.shtml
    http://www.80diy.com/home/20050527/17/4040711.html

    5,
    org.apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request failed. Read timed out
    HTTP活動超時限制的時間太短 HTTP Keep-Alive Timeout.

    6,InputStream is =formFile.getInputStream() ;? //formFile是org.apache.struts.upload.FormFile
    上傳的文件小時這個輸入流是java.io.ByteArrayInputStream,上傳比較大的文件時這個輸入流是FileInputStream

    7,設置表單里的上傳路徑為只讀
    <input type=file id="uploadfile" name="uploadfile" style="display: none;">
    <input type=text id=tempfile readonly="true">
    <input type=button
    onClick="uploadfile.click();tempfile.value=uploadfile.value;" value="瀏覽..">

    10,
    http://eastpoint.javaeye.com/blog/99084
    http://topic.csdn.net/u/20080131/13/649c57c7-204e-4bb6-9b09-49cca39f00b8.html
    http://blog.niwota.com/nb/chenchuang?cat_self_id=291075

    評論

    # re: 使用commons fileupload的零碎筆記  回復  更多評論   

    2008-10-31 15:27 by leekiang
    對于post和get的參數,好像commons fileupload的處理是不一樣的,get參數可以直接通過request.getParameter()的方式獲取,而post的不行,待驗證。

    # re: 使用commons fileupload的零碎筆記  回復  更多評論   

    2009-07-23 10:24 by 尹偉杰
    我現在就遇到了這樣的問題

    # re: 使用commons fileupload的零碎筆記  回復  更多評論   

    2009-07-23 10:27 by 尹偉杰
    一次性上傳衛星照片4個 大于2G weblogic報錯 超時 但是 改成4個form分開
    一個form 965m 也報錯 都暈了,你當時是怎么解決的???
    我的qq是838303967

    # re: 使用commons fileupload的零碎筆記  回復  更多評論   

    2009-07-23 10:29 by 尹偉杰
    Processing of multipart/form-data request failed. EOF after reading only: '38535168' of: '967898783' promised bytes, out of which at least: '0' were already buffered 報的錯!!!

    # re: 使用commons fileupload的零碎筆記  回復  更多評論   

    2009-07-28 18:49 by 尹偉杰
    哥們你趕快上線啊!!我的快瘋了!!!我的電話是13146277259 qq是838303967!!!

    # re: 使用commons fileupload的零碎筆記  回復  更多評論   

    2010-08-30 21:58 by gogoes
    throw new IOFileUploadException(//報錯經常在這里
    "Processing of " + MULTIPART_FORM_DATA
    + " request failed. " + e.getMessage(), e);


    我現在處理大量用戶數據時,老是這里出錯,出錯信息如下:
    Caused by: org.apache.commons.fileupload.FileUploadException: Processing of multipart/form-data request failed. Stream ended unexpectedly
    at com.alibaba.service.upload.patch.ServletFileUpload.parseRequest(ServletFileUpload.java:162)
    at com.alibaba.service.upload.patch.ServletFileUpload.parseRequest(ServletFileUpload.java:40)
    at com.alibaba.service.upload.DefaultUploadService.parseRequest(DefaultUploadService.java:165)

    能幫看看,有什么解決的辦法嗎?
    主站蜘蛛池模板: 亚洲人成www在线播放| 大胆亚洲人体视频| 很黄很黄的网站免费的| 三年片在线观看免费观看大全动漫 | 99在线在线视频免费视频观看| 成人电影在线免费观看| 免费无码黄网站在线看| 免费毛片a线观看| 日韩中文字幕免费视频| 99久久精品国产免费| 95老司机免费福利| 国产h视频在线观看网站免费| 青娱乐免费在线视频| 成人免费午夜在线观看| 日韩高清在线免费看| 日韩精品成人亚洲专区| 亚洲综合最新无码专区| 国产亚洲综合一区柠檬导航| 亚洲男人第一av网站| 亚洲国色天香视频| 亚洲中文字幕无码久久2020| 国产亚洲欧美日韩亚洲中文色| 国产亚洲美女精品久久| 中国毛片免费观看| 一区二区免费视频| 无码免费午夜福利片在线| 国产免费久久精品久久久| 中文字幕日韩亚洲| 亚洲国产美国国产综合一区二区| 亚洲成a人不卡在线观看| 亚洲人成欧美中文字幕| 一级做a爰片性色毛片免费网站| 爽爽爽爽爽爽爽成人免费观看| 最近免费2019中文字幕大全| 免费av欧美国产在钱| 亚洲 无码 在线 专区| 亚洲精品国产精品乱码在线观看| 亚洲欧洲自拍拍偷综合| 香蕉视频亚洲一级| 免费91最新地址永久入口 | 九九九精品视频免费|