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

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

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

    CONAN ZONE

    你越掙扎我就越興奮

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      0 Posts :: 282 Stories :: 0 Comments :: 0 Trackbacks
    前一段時(shí)間剛來公司,看到一個(gè)項(xiàng)目中以前有人寫的struts代碼。是使用了FormFile來處理關(guān)于文件上傳的模塊。但是用力一段時(shí)間后,發(fā)現(xiàn)出問題了。寫完的這個(gè)模塊,上傳文件是沒有問題的,但是當(dāng)服務(wù)器的空間較小的時(shí)候,穿一個(gè)比較大的文件就出問題了,文件還沒有上傳完,就拋出一個(gè)錯(cuò)誤的頁面,報(bào)告上傳模塊出了問題,而且是Tomcat默認(rèn)的出錯(cuò)頁面。 于是想辦法,修改,查看源代碼,發(fā)現(xiàn)原來寫這段代碼的人是默認(rèn)等文件上傳完以后進(jìn)入Action了才判斷文件大小是否超出了限制。 但是,默認(rèn)配置下使用struts的FormFile比較特殊,F(xiàn)ormFile是struts包對外的一個(gè)接口,而且org.apache.struts.upload包是使用的commons-fileupload-1.0進(jìn)行的封裝。如果使用了它來實(shí)現(xiàn)文件上傳的功能,則必須是FormFile對象在被初始化以后才能使用,那什么時(shí)候它才是被初始化的呢? 答案是:在進(jìn)入Action之前就已經(jīng)初始化好了! 因此,原先的設(shè)計(jì):在Action中判斷文件大小是根本不能在上傳過程中起到提示作用的,因?yàn)檫@時(shí)候文件已經(jīng)上傳完了。而且這個(gè)設(shè)計(jì)還有一個(gè)確定就是不能捕獲上傳過程中出現(xiàn)的任何問題。也就是說:在Action里我們得到的FormFile對象是上傳的一個(gè)結(jié)果,而不是一個(gè)未上傳好就可以使用的對象! 那如何控制FormFile上傳的過程呢?顯然,在Action里處理已經(jīng)不能奏效了,想想別的辦法,讓我們翻看一下Struts的源代碼找找靈感吧。 這是struts1.1的org.apache.struts.upload包的描述: (見附件) 從上圖我們可以看出有有CommonsMultipartRequestHandler和DiskMultipartRequestHandler兩個(gè)類實(shí)現(xiàn)了MultipartRequestHandler接口。 大家都知道,Commons-fileupload控件在上傳的時(shí)候,使用的enctype為:enctype="multipart/form-data",因此不難看出MultipartRequestHandler的實(shí)現(xiàn)就是來處理enctype="multipart/form-data"這樣的post請求的。 但是這里有兩個(gè)類,CommonsMultipartRequestHandler和DiskMultipartRequestHandler。到底哪個(gè)是處理FormFile的上傳的呢?這個(gè)問題應(yīng)該從org.apache.struts.config包里來找。 org.apache.struts.config包是用來處理struts配置文件的數(shù)據(jù)的包。找到org.apache.struts.config. ControllerConfig。 看這幾行:

     1 protected String multipartClass =     
     2 "org.apache.struts.upload.CommonsMultipartRequestHandler";      
     3         
     4 public String getMultipartClass()     
     5 {             
     6      return (this.multipartClass);         
     7 }          
     8    
     9 public void setMultipartClass(String multipartClass)     
    10 {             
    11      if (configured)     
    12      {                 
    13            throw new IllegalStateException("Configuration is frozen");                      
    14      }      
    15             
    16      this.multipartClass = multipartClass;        
    17 }     
    18 


     1 /**        
     2 * The fully qualified Java class name of the MultipartRequestHandler        
     3 * class to be used.        
     4 */        
     5 protected String multipartClass =    
     6 "org.apache.struts.upload.CommonsMultipartRequestHandler";     
     7        
     8 public String getMultipartClass()    
     9 {            
    10      return (this.multipartClass);        
    11 }         
    12   
    13 public void setMultipartClass(String multipartClass)    
    14 {            
    15      if (configured)    
    16      {                
    17            throw new IllegalStateException("Configuration is frozen");                     
    18      }     
    19            
    20      this.multipartClass = multipartClass;       
    21 }    
    22 

    這幾行的意思很明白,如果沒有在配置文件中配置MultipartRequestHandler實(shí)現(xiàn)類的絕對路徑,那就使用org.apache.struts.upload.CommonsMultipartRequestHandler類默認(rèn)處理。 ^_^,這就是關(guān)鍵了:struts是默認(rèn)使用org.apache.struts.upload.CommonsMultipartRequestHandler類來處理FormFile指定的上傳文件的。 馬上轉(zhuǎn)到org.apache.struts.upload.CommonsMultipartRequestHandler來看看:

    1 /**       
    2 *默認(rèn)文件上傳的大小是250M       
    3 */        
    4 public static final long DEFAULT_SIZE_MAX = 250 * 1024 * 1024;         
    5 /**       
    6 *上傳文件在內(nèi)存中使用的緩沖區(qū)大小,超過次數(shù)值的數(shù)據(jù)寫入硬盤。       
    7 */        
    8 public static final int DEFAULT_SIZE_THRESHOLD = 256 * 1024;   

    1 /**      
    2 *默認(rèn)文件上傳的大小是250M      
    3 */       
    4 public static final long DEFAULT_SIZE_MAX = 250 * 1024 * 1024;        
    5 /**      
    6 *上傳文件在內(nèi)存中使用的緩沖區(qū)大小,超過次數(shù)值的數(shù)據(jù)寫入硬盤。      
    7 */       
    8 public static final int DEFAULT_SIZE_THRESHOLD = 256 * 1024;   


    還有,最最重要的實(shí)現(xiàn)方法:

     1 /**       
     2 * Parses the input stream and partitions the parsed items into a set of       
     3 * form fields and a set of file items. In the process, the parsed items       
     4 * are translated from Commons FileUpload <code>FileItem</code> instances       
     5 * to Struts <code>FormFile</code> instances.    
     6 @param request The multipart request to be processed.     
     7 @throws ServletException if an unrecoverable error occurs.                  
     8 就是這個(gè)函數(shù)處理上傳文件的request,把request交給Commons FileUpload 控件處理,并解析FileItem轉(zhuǎn)換成Struts的FormFile。       
     9 */   
    10 public void handleRequest(HttpServletRequest request) throws ServletException    
    11 

     1 /**      
     2 * Parses the input stream and partitions the parsed items into a set of      
     3 * form fields and a set of file items. In the process, the parsed items      
     4 * are translated from Commons FileUpload <code>FileItem</code> instances      
     5 * to Struts <code>FormFile</code> instances.   
     6 @param request The multipart request to be processed.    
     7 @throws ServletException if an unrecoverable error occurs.                 
     8 就是這個(gè)函數(shù)處理上傳文件的request,把request交給Commons FileUpload 控件處理,并解析FileItem轉(zhuǎn)換成Struts的FormFile。      
     9 */  
    10 public void handleRequest(HttpServletRequest request) throws ServletException 

    再看看這個(gè)函數(shù)內(nèi)部是怎么實(shí)現(xiàn)的吧?

    1 // 使用了DiskFileUpload。      
    2 // (Commons-FileUpload很老版本的一個(gè)上傳實(shí)現(xiàn)類了,還在用?我的顯示是Deprecated)        
    3 DiskFileUpload upload = new DiskFileUpload();        
    4 // 上傳最大值        
    5 upload.setSizeMax((int) getSizeMax(ac));        
    6 // 上傳文件在內(nèi)存中使用的緩沖區(qū)大小        
    7 upload.setSizeThreshold((int) getSizeThreshold(ac));        
    8 // 存在硬盤的什么地方,一般是默認(rèn)    
    9 pload.setRepositoryPath(getRepositoryPath(ac));    


    1 // 使用了DiskFileUpload。     
    2 // (Commons-FileUpload很老版本的一個(gè)上傳實(shí)現(xiàn)類了,還在用?我的顯示是Deprecated)       
    3 DiskFileUpload upload = new DiskFileUpload();       
    4 // 上傳最大值       
    5 upload.setSizeMax((int) getSizeMax(ac));       
    6 // 上傳文件在內(nèi)存中使用的緩沖區(qū)大小       
    7 upload.setSizeThreshold((int) getSizeThreshold(ac));       
    8 // 存在硬盤的什么地方,一般是默認(rèn)   
    9 pload.setRepositoryPath(getRepositoryPath(ac));    


    接著看handleRequest如何處理request的:

     1 // Parse the request into file items.                
     2 List items = null;                
     3 try     
     4 {                    
     5      items = upload.parseRequest(request);                
     6 }    
     7 //這里是關(guān)鍵:上傳過程中出了超出最大值的異常了,如何處理?          
     8 catch (DiskFileUpload.SizeLimitExceededException e)     
     9 {                     
    10      // Special handling for uploads that are too big          
    11      request.setAttribute(    
    12 MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED,    
    13            Boolean.TRUE);                    
    14      return;                
    15 }                     
    16 //出了其他異常,如enctype不對,磁盤空間不足怎么辦?        
    17 catch (FileUploadException e)     
    18 {                    
    19      log.error("Failed to parse multipart request", e);                    
    20      throw new ServletException(e);                
    21 }    
    22 


     1 // Parse the request into file items.               
     2 List items = null;               
     3 try    
     4 {                   
     5      items = upload.parseRequest(request);               
     6 }   
     7 //這里是關(guān)鍵:上傳過程中出了超出最大值的異常了,如何處理?         
     8 catch (DiskFileUpload.SizeLimitExceededException e)    
     9 {                    
    10      // Special handling for uploads that are too big         
    11      request.setAttribute(   
    12 MultipartRequestHandler.ATTRIBUTE_MAX_LENGTH_EXCEEDED,   
    13            Boolean.TRUE);                   
    14      return;               
    15 }                    
    16 //出了其他異常,如enctype不對,磁盤空間不足怎么辦?       
    17 catch (FileUploadException e)    
    18 {                   
    19      log.error("Failed to parse multipart request", e);                   
    20      throw new ServletException(e);               
    21 }   
    22 


    這次一目了然了: Struts根本沒有把上傳過程中出的超出最大值的異常帶到Action,而是把它放到了rquest的Attribute里。 而出了其他異常如enctype不對,磁盤空間不足怎么辦?很遺憾,Struts沒有去處理它,而是log了一下,拋給了上一層了。 那我一定要獲得這些全部異常咋辦呢?沒辦法,自己定制一個(gè)MultipartRequestHandler吧,那樣就能徹底解決上傳過程中的控制問題了! 在此之前,我們得先去最新版的commons-fileupload控件看看上傳過程中可能拋出多少異常?

     1 //所有上傳異常的父類    
     2 org.apache.commons.fileupload.FileUploadException     
     3 //注意:這個(gè)類的類名是FileUploadBase.SizeLimitExceededException是個(gè)public內(nèi)    
     4 //部類。上傳的formdata總的數(shù)據(jù)超出了規(guī)定大小    
     5 org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException     
     6 //注意:也是個(gè)內(nèi)部類。這個(gè)才是上傳的文件超出了規(guī)定大小    
     7 org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException    
     8 //其它的,也看看吧:    
     9 org.apache.commons.fileupload.FileUploadBase.FileUploadIOException    
    10 org.apache.commons.fileupload.FileUploadBase.InvalidContentTypeException    
    11 org.apache.commons.fileupload.FileUploadBase.IOFileUploadException    
    12 org.apache.commons.fileupload.FileUploadBase.UnknownSizeException

     1 //所有上傳異常的父類   
     2 org.apache.commons.fileupload.FileUploadException    
     3 //注意:這個(gè)類的類名是FileUploadBase.SizeLimitExceededException是個(gè)public內(nèi)   
     4 //部類。上傳的formdata總的數(shù)據(jù)超出了規(guī)定大小   
     5 org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException    
     6 //注意:也是個(gè)內(nèi)部類。這個(gè)才是上傳的文件超出了規(guī)定大小   
     7 org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException   
     8 //其它的,也看看吧:   
     9 org.apache.commons.fileupload.FileUploadBase.FileUploadIOException   
    10 org.apache.commons.fileupload.FileUploadBase.InvalidContentTypeException   
    11 org.apache.commons.fileupload.FileUploadBase.IOFileUploadException   
    12 org.apache.commons.fileupload.FileUploadBase.UnknownSizeException    

    要想獲得盡可能仔細(xì)的數(shù)據(jù)就在處理的try/catch塊里把上面的異常都catch一下,放到request的attribute里去就OK了。 另外還有要說的是,最好用commons-fileupload控件的最新版本,因?yàn)镈iskFileUpload這個(gè)類,commons-fileupload已經(jīng)棄用了,取而代之的是ServletFileUpload類了,所以一定要注意!切記,切記….. 這是我寫的CommonsMultipartRequestHandler替代類的public void handleRequest(HttpServletRequest request) throws ServletException函數(shù):

      1 public void handleRequest(HttpServletRequest request) throws ServletException    
      2 {    
      3      // Get the app config for the current request.    
      4      ModuleConfig ac = (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);    
      5    
      6      // DiskFileItem工廠,主要用來設(shè)定上傳文件的參數(shù)    
      7      DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();    
      8    
      9      // 上傳文件所用到的緩沖區(qū)大小,超過此緩沖區(qū)的部分將被寫入到磁盤    
     10      fileItemFactory.setSizeThreshold((intthis.getSizeThreshold(ac));    
     11    
     12      // 上傳文件用到的臨時(shí)文件存放位置    
     13      fileItemFactory.setRepository(this.getRepository(ac));    
     14    
     15      // 使用fileItemFactory為參數(shù)實(shí)例化一個(gè)ServletFileUpload對象    
     16      // 注意:該對象為commons-fileupload-1.2新增的類.    
     17      // 對于1.2以下的commons-fileupload版本并不存在此類.    
     18      ServletFileUpload upload = new ServletFileUpload(fileItemFactory);    
     19    
     20      // 從session中讀取對本次上傳文件的最大值的限制    
     21      String maxUploadSize = (String)request.getSession().    
     22 getAttribute(BasicConstants.maxUploadSize);    
     23    
     24      // 獲取struts-config文件中controller標(biāo)簽的maxFileSize屬性來確定默認(rèn)上傳的限制    
     25      // 如果struts-config文件中controller標(biāo)簽的maxFileSize屬性沒設(shè)置則使用默認(rèn)的上傳限制250M.    
     26      long defaultOrConfigedMaxUploadSize = this.getSizeMax(ac);    
     27      if (maxUploadSize != null && maxUploadSize != "")    
     28      {    
     29           // 如果maxUploadSize設(shè)定不正確則上傳限制為defaultOrConfigedMaxUploadSize的值    
     30    
     31           // 正確則為maxUploadSize轉(zhuǎn)換成的字節(jié)數(shù)    
     32           upload.setSizeMax((longthis.convertSizeToBytes(    
     33 maxUploadSize, defaultOrConfigedMaxUploadSize));    
     34           
     35       }    
     36       else   
     37       {    
     38           // 如果maxUploadSize沒設(shè)置則使用默認(rèn)的上傳限制     
     39           upload.setSizeMax(defaultOrConfigedMaxUploadSize);    
     40       }     
     41    
     42       // 從session中清空maxUploadSize    
     43       request.getSession().removeAttribute("maxUploadSize");     
     44    
     45       // Create the hash tables to be populated.    
     46       elementsText = new Hashtable();    
     47       elementsFile = new Hashtable();    
     48       elementsAll = new Hashtable();     
     49    
     50       // Parse the request into file items.    
     51       List items = null;    
     52       // ServletFileUpload類來處理表單請求    
     53       // 拋出的異常為FileUploadException的子異常    
     54       // 如果捕獲這些異常就將捕獲的異常放到session中返回.    
     55    
     56       try   
     57       {    
     58             items = upload.parseRequest(request);    
     59    
     60       }    
     61       catch (FileUploadBase.SizeLimitExceededException e)    
     62       {    
     63    
     64             // 請求數(shù)據(jù)的size超出了規(guī)定的大小.    
     65             request.getSession().setAttribute(    
     66                 BasicConstants.baseSizeLimitExceededException, e);    
     67             return;    
     68       }    
     69       catch (FileUploadBase.FileSizeLimitExceededException e)    
     70       {    
     71             // 請求文件的size超出了規(guī)定的大小.    
     72             request.getSession().setAttribute(    
     73                 BasicConstants.baseFileSizeLimitExceededException, e);    
     74             return;    
     75       }    
     76       catch (FileUploadBase.IOFileUploadException e)    
     77       {    
     78             // 文件傳輸出現(xiàn)錯(cuò)誤,例如磁盤空間不足等.    
     79             request.getSession().setAttribute(    
     80                 BasicConstants.baseIOFileUploadException, e);    
     81             return;    
     82       }    
     83       catch (FileUploadBase.InvalidContentTypeException e)    
     84       {    
     85             // 無效的請求類型,即請求類型enctype != "multipart/form-data"    
     86             request.getSession().setAttribute(    
     87                 BasicConstants.baseInvalidContentTypeException, e);    
     88             return;    
     89       }    
     90       catch (FileUploadException e)    
     91       {    
     92            // 如果都不是以上子異常,則拋出此總的異常,出現(xiàn)此異常原因無法說明.    
     93            request.getSession().setAttribute(    
     94                 BasicConstants.FileUploadException, e);    
     95            return;    
     96       }    
     97    
     98       // Partition the items into form fields and files.    
     99       Iterator iter = items.iterator();    
    100           
    101       while (iter.hasNext())    
    102       {    
    103             FileItem item = (FileItem) iter.next();    
    104    
    105             if (item.isFormField())    
    106             {    
    107                    addTextParameter(request, item);    
    108             }    
    109             else   
    110             {    
    111                    addFileParameter(item);    
    112             }    
    113       }    
    114 }   
    115 

      1 public void handleRequest(HttpServletRequest request) throws ServletException   
      2 {   
      3      // Get the app config for the current request.   
      4      ModuleConfig ac = (ModuleConfig) request.getAttribute(Globals.MODULE_KEY);   
      5   
      6      // DiskFileItem工廠,主要用來設(shè)定上傳文件的參數(shù)   
      7      DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();   
      8   
      9      // 上傳文件所用到的緩沖區(qū)大小,超過此緩沖區(qū)的部分將被寫入到磁盤   
     10      fileItemFactory.setSizeThreshold((intthis.getSizeThreshold(ac));   
     11   
     12      // 上傳文件用到的臨時(shí)文件存放位置   
     13      fileItemFactory.setRepository(this.getRepository(ac));   
     14   
     15      // 使用fileItemFactory為參數(shù)實(shí)例化一個(gè)ServletFileUpload對象   
     16      // 注意:該對象為commons-fileupload-1.2新增的類.   
     17      // 對于1.2以下的commons-fileupload版本并不存在此類.   
     18      ServletFileUpload upload = new ServletFileUpload(fileItemFactory);   
     19   
     20      // 從session中讀取對本次上傳文件的最大值的限制   
     21      String maxUploadSize = (String)request.getSession().   
     22 getAttribute(BasicConstants.maxUploadSize);   
     23   
     24      // 獲取struts-config文件中controller標(biāo)簽的maxFileSize屬性來確定默認(rèn)上傳的限制   
     25      // 如果struts-config文件中controller標(biāo)簽的maxFileSize屬性沒設(shè)置則使用默認(rèn)的上傳限制250M.   
     26      long defaultOrConfigedMaxUploadSize = this.getSizeMax(ac);   
     27      if (maxUploadSize != null && maxUploadSize != "")   
     28      {   
     29           // 如果maxUploadSize設(shè)定不正確則上傳限制為defaultOrConfigedMaxUploadSize的值   
     30   
     31           // 正確則為maxUploadSize轉(zhuǎn)換成的字節(jié)數(shù)   
     32           upload.setSizeMax((longthis.convertSizeToBytes(   
     33 maxUploadSize, defaultOrConfigedMaxUploadSize));   
     34          
     35       }   
     36       else  
     37       {   
     38           // 如果maxUploadSize沒設(shè)置則使用默認(rèn)的上傳限制    
     39           upload.setSizeMax(defaultOrConfigedMaxUploadSize);   
     40       }    
     41   
     42       // 從session中清空maxUploadSize   
     43       request.getSession().removeAttribute("maxUploadSize");    
     44   
     45       // Create the hash tables to be populated.   
     46       elementsText = new Hashtable();   
     47       elementsFile = new Hashtable();   
     48       elementsAll = new Hashtable();    
     49   
     50       // Parse the request into file items.   
     51       List items = null;   
     52       // ServletFileUpload類來處理表單請求   
     53       // 拋出的異常為FileUploadException的子異常   
     54       // 如果捕獲這些異常就將捕獲的異常放到session中返回.   
     55   
     56       try  
     57       {   
     58             items = upload.parseRequest(request);   
     59   
     60       }   
     61       catch (FileUploadBase.SizeLimitExceededException e)   
     62       {   
     63   
     64             // 請求數(shù)據(jù)的size超出了規(guī)定的大小.   
     65             request.getSession().setAttribute(   
     66                 BasicConstants.baseSizeLimitExceededException, e);   
     67             return;   
     68       }   
     69       catch (FileUploadBase.FileSizeLimitExceededException e)   
     70       {   
     71             // 請求文件的size超出了規(guī)定的大小.   
     72             request.getSession().setAttribute(   
     73                 BasicConstants.baseFileSizeLimitExceededException, e);   
     74             return;   
     75       }   
     76       catch (FileUploadBase.IOFileUploadException e)   
     77       {   
     78             // 文件傳輸出現(xiàn)錯(cuò)誤,例如磁盤空間不足等.   
     79             request.getSession().setAttribute(   
     80                 BasicConstants.baseIOFileUploadException, e);   
     81             return;   
     82       }   
     83       catch (FileUploadBase.InvalidContentTypeException e)   
     84       {   
     85             // 無效的請求類型,即請求類型enctype != "multipart/form-data"   
     86             request.getSession().setAttribute(   
     87                 BasicConstants.baseInvalidContentTypeException, e);   
     88             return;   
     89       }   
     90       catch (FileUploadException e)   
     91       {   
     92            // 如果都不是以上子異常,則拋出此總的異常,出現(xiàn)此異常原因無法說明.   
     93            request.getSession().setAttribute(   
     94                 BasicConstants.FileUploadException, e);   
     95            return;   
     96       }   
     97   
     98       // Partition the items into form fields and files.   
     99       Iterator iter = items.iterator();   
    100          
    101       while (iter.hasNext())   
    102       {   
    103             FileItem item = (FileItem) iter.next();   
    104   
    105             if (item.isFormField())   
    106             {   
    107                    addTextParameter(request, item);   
    108             }   
    109             else  
    110             {   
    111                    addFileParameter(item);   
    112             }   
    113       }   
    114 }  
    115 

    其它部分均未做什么大改變。 好了,替代類寫好了,我們怎么去用呢? 這樣:在struts-config文件中寫配置:

     1 <!-- ========== Controller Configuration ================================ -->   
     2    
     3        <controller>   
     4    
     5               <!-- The "input" parameter on "action" elements is the name of a    
     6    
     7                      local or global "forward" rather than a module-relative path -->   
     8    
     9               <set-property value="true" property="inputForward" />   
    10               <set-property value="text/html; charset=UTF-8"   
    11                      property="contentType" />   
    12               <!-- 通過寫類的全名來替代struts默認(rèn)的MultipartRequestHandler -->                 
    13    
    14               <set-property property="multipartClass"     
    15 value="com.amplesky.commonmodule.struts.AmpleskyMultipartRequestHandler" />   
    16               <!-- 規(guī)定的上傳文件的最大值 -->   
    17               <set-property property="maxFileSize" value="15M" />   
    18               <!--  緩沖區(qū)大小 -->   
    19               <set-property property="memFileSize" value="5M" />   
    20        </controller>   
    21 

     1 <!-- ========== Controller Configuration ================================ -->  
     2   
     3        <controller>  
     4   
     5               <!-- The "input" parameter on "action" elements is the name of a   
     6   
     7                      local or global "forward" rather than a module-relative path -->  
     8   
     9               <set-property value="true" property="inputForward" />  
    10               <set-property value="text/html; charset=UTF-8"  
    11                      property="contentType" />  
    12               <!-- 通過寫類的全名來替代struts默認(rèn)的MultipartRequestHandler -->                
    13   
    14               <set-property property="multipartClass"    
    15 value="com.amplesky.commonmodule.struts.AmpleskyMultipartRequestHandler" />  
    16               <!-- 規(guī)定的上傳文件的最大值 -->  
    17               <set-property property="maxFileSize" value="15M" />  
    18               <!--  緩沖區(qū)大小 -->  
    19               <set-property property="memFileSize" value="5M" />  
    20        </controller>  
    21 

    好了!現(xiàn)在我們再用FormFile上傳文件,可以在上傳之前動(dòng)態(tài)設(shè)置或者從配置文件設(shè)置上傳文件的大小,一旦上傳過程中出現(xiàn)了異常,就會被寫入request的attributs里。當(dāng)進(jìn)入action的時(shí)候,通過在Action里獲取異常就可以判斷上傳過程中出了什么問題了,而且在上傳過程中文件一旦超出了規(guī)定大小,或者磁盤大小不足的情況會立即中斷上傳的。這樣我們的功能就實(shí)現(xiàn)了。 最后,感慨一下, 1.感覺commons-fileupload還是挺好用的,但是FormFile的使用不大好,基本上誤導(dǎo)能力很強(qiáng),網(wǎng)上關(guān)于FormFile的資料說明很少,以上這些都是我自己摸索出來的。 2.Struts 1都到了1.3版本了,但是對于FormFile的實(shí)現(xiàn)依然使用commons-fileupload-1.0版本的DiskFileUpload類,可見更新也不怎么樣。其實(shí)我覺得這是apache大部分開源工具的一個(gè)通病:更新確實(shí)不怎么快,commons框架里邊的源代碼和jar包不一致,還有很多是2004或者2003年的…要命的是居然不支持javase5的新特性???? 3. 認(rèn)為把異常放到request的attributs里不好,曾經(jīng)嘗試過拋出異常然后通過配置exception-controller來抓去異常處理,但是抓不到,怎么都抓不到,后來翻了大半天源碼才發(fā)現(xiàn):struts在處理異常請求的時(shí)候?qū)⒊霈F(xiàn)的ServletException和IOExcepton都交給了上層去處理了,根本不會拋出來。所以這兩種異常是抓不到的。


    posted on 2008-07-10 19:25 CONAN 閱讀(3494) 評論(0)  編輯  收藏 所屬分類: Struts
    主站蜘蛛池模板: 日韩精品亚洲人成在线观看 | 最近2022中文字幕免费视频| 亚洲综合久久一本伊伊区| 亚洲?V乱码久久精品蜜桃| 国产精品免费观看| 久草视频在线免费看| 一区二区三区免费在线视频| 亚洲中文字幕无码中文字| 亚洲国产精品婷婷久久| 亚洲国产精品SSS在线观看AV | 精品久久久久久久久亚洲偷窥女厕 | 国产精品视频免费一区二区三区| 免费一区二区三区| 国产猛男猛女超爽免费视频| 一级毛片在播放免费| 日韩在线视频播放免费视频完整版| 亚洲影院天堂中文av色| 国产亚洲精品影视在线| 亚洲性线免费观看视频成熟| 亚洲免费电影网站| 亚洲JIZZJIZZ妇女| 国产成人综合亚洲| 国产免费内射又粗又爽密桃视频| 国产精品亚洲а∨无码播放不卡 | 久久久久亚洲精品男人的天堂| 亚洲国产成人久久一区WWW| 亚洲AV无码成H人在线观看| 久久夜色精品国产亚洲| 久久精品国产亚洲av影院| 亚洲精品日韩中文字幕久久久| 亚洲一欧洲中文字幕在线| 亚洲国产精品无码中文lv| 免费无毒a网站在线观看| 免费国产99久久久香蕉| 四虎永久在线精品免费观看视频| 韩国欧洲一级毛片免费| 亚洲乱码一区二区三区在线观看 | 亚洲国产精品视频| 亚洲黄页网在线观看| 在线免费观看h片| 妞干网免费视频在线观看|