JSF文件上传

JSF2.0虽然添加了很多新特性,但是还是没有官方的对上传的支持。直接使用

<h:form enctype="multipart/form-data" >

</h:form>

是不行的。因为multipart/form-data类型的request是解析不了的。

解决方法可以使用filter对request进行包装(原request似乎是不能更改的,所以借助包装),在解析request是可以借助apache的commons-fileupload组件。

Myfaces刚好给出了这个解决方案的实现:

MultipartFilter+MultipartRequestWrapper(Use commons-fileupload).

 

原来是打包在一个myfaces-extensions.jar中,现在找不到官方的下载,不过在Tomahawk包里可以找到(org.apache.myfaces.webapp.filter.*,MultipartFilter似乎都弄到ExtensionsFilter里了)。

 

个人觉得旧版的源代码挺参考价值的,贴出来分享下。

 MultipartRequestWrapper:

 

  1. 1 /* 
  2. 2  * Copyright 2004 The Apache Software Foundation. 
  3. 3  *  
  4. 4  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5. 5  * you may not use this file except in compliance with the License. 
  6. 6  * You may obtain a copy of the License at 
  7. 7  *  
  8. 8  * http://www.apache.org/licenses/LICENSE-2.0 
  9. 9  *  
  10. 10  * Unless required by applicable law or agreed to in writing, software 
  11. 11  * distributed under the License is distributed on an "AS IS" BASIS, 
  12. 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13. 13  * See the License for the specific language governing permissions and 
  14. 14  * limitations under the License. 
  15. 15  */  
  16. 16 package org.apache.myfaces.component.html.util;  
  17. 17   
  18. 18 import org.apache.commons.fileupload.*;  
  19. 19 import org.apache.commons.logging.Log;  
  20. 20 import org.apache.commons.logging.LogFactory;  
  21. 21   
  22. 22 import javax.servlet.http.HttpServletRequest ;  
  23. 23 import javax.servlet.http.HttpServletRequestWrapper ;  
  24. 24 import java.io.UnsupportedEncodingException ;  
  25. 25 import java.util.*;  
  26. 26   
  27. 27 /** 
  28. 28  * @author Sylvain Vieujot (latest modification by $Author: svieujot $) 
  29. 29  * @version $Revision: 1.2 $ $Date: 2004/12/11 21:41:33 $ 
  30. 30  * $Log: MultipartRequestWrapper.java,v $ 
  31. 31  * Revision 1.2 2004/12/11 21:41:33 svieujot 
  32. 32  * Add method to get the FileItems. 
  33. 33  * 
  34. 34  * Revision 1.1 2004/12/01 16:32:03 svieujot 
  35. 35  * Convert the Multipart filter in an ExtensionsFilter that provides an additional facility to include resources in a page. 
  36. 36  * Tested only with javascript resources right now, but should work fine with images too. 
  37. 37  * Some work to do to include css resources. 
  38. 38  * The popup component has been converted to use this new Filter. 
  39. 39  * 
  40. 40  * Revision 1.8 2004/11/16 16:25:52 mmarinschek 
  41. 41  * new popup - component; not yet finished 
  42. 42  * 
  43. 43  * Revision 1.7 2004/10/13 11:50:57 matze 
  44. 44  * renamed packages to org.apache 
  45. 45  * 
  46. 46  * Revision 1.6 2004/09/09 13:43:59 manolito 
  47. 47  * query string parameters where missing in the parameter map 
  48. 48  * 
  49. 49  * Revision 1.5 2004/08/16 18:06:47 svieujot 
  50. 50  * Another bug fix for bug #1001511. Patch submitted by Takashi Okamoto. 
  51. 51  * 
  52. 52  * Revision 1.4 2004/08/02 04:26:06 svieujot 
  53. 53  * Fix for bug #1001511 : setHeaderEncoding 
  54. 54  * 
  55. 55  */  
  56. 56 public class MultipartRequestWrapper  
  57. 57         extends HttpServletRequestWrapper   
  58. 58 {  
  59. 59     private static Log log = LogFactory.getLog(MultipartRequestWrapper.class);  
  60. 60   
  61. 61     HttpServletRequest  request = null;  
  62. 62     HashMap parametersMap = null;  
  63. 63     DiskFileUpload fileUpload = null;  
  64. 64     HashMap fileItems = null;  
  65. 65     int maxSize;  
  66. 66     int thresholdSize;  
  67. 67     String  repositoryPath;  
  68. 68   
  69. 69     public MultipartRequestWrapper(HttpServletRequest  request,   
  70. 70                                    int maxSize, int thresholdSize,  
  71. 71                                    String  repositoryPath){  
  72. 72         super( request );  
  73. 73         this.request = request;  
  74. 74         this.maxSize = maxSize;  
  75. 75         this.thresholdSize = thresholdSize;  
  76. 76         this.repositoryPath = repositoryPath;  
  77. 77     }  
  78. 78       
  79. 79     private void parseRequest() {  
  80. 80         fileUpload = new DiskFileUpload();  
  81. 81         fileUpload.setFileItemFactory(new DefaultFileItemFactory());  
  82. 82         fileUpload.setSizeMax(maxSize);  
  83. 83   
  84. 84         fileUpload.setSizeThreshold(thresholdSize);  
  85. 85   
  86. 86         if(repositoryPath != null && repositoryPath.trim().length()>0)  
  87. 87             fileUpload.setRepositoryPath(repositoryPath);  
  88. 88   
  89. 89         String  charset = request.getCharacterEncoding();  
  90. 90         fileUpload.setHeaderEncoding(charset);  
  91. 91   
  92. 92   
  93. 93         List requestParameters = null;  
  94. 94         try{  
  95. 95             requestParameters = fileUpload.parseRequest(request);  
  96. 96         } catch (FileUploadBase.SizeLimitExceededException e) {  
  97. 97   
  98. 98             // TODO: find a way to notify the user about the fact that the uploaded file exceeded size limit  
  99. 99   
  100. 100             if(log.isInfoEnabled())  
  101. 101                 log.info("user tried to upload a file that exceeded file-size limitations.",e);  
  102. 102   
  103. 103             requestParameters = Collections.EMPTY_LIST;  
  104. 104   
  105. 105         }catch(FileUploadException fue){  
  106. 106             log.error("Exception while uploading file.", fue);  
  107. 107             requestParameters = Collections.EMPTY_LIST;  
  108. 108         }  
  109. 109   
  110. 110         parametersMap = new HashMap( requestParameters.size() );  
  111. 111         fileItems = new HashMap();  
  112. 112   
  113. 113         for (Iterator iter = requestParameters.iterator(); iter.hasNext(); ){  
  114. 114             FileItem fileItem = (FileItem) iter.next();  
  115. 115   
  116. 116             if (fileItem.isFormField()) {  
  117. 117                 String  name = fileItem.getFieldName();  
  118. 118   
  119. 119                 // The following code avoids commons-fileupload charset problem.  
  120. 120 // After fixing commons-fileupload, this code should be  
  121. 121 //  
  122. 122 // String value = fileItem.getString();  
  123. 123 //  
  124. 124 String  value = null;  
  125. 125                 if ( charset == null) {  
  126. 126                     value = fileItem.getString();  
  127. 127                 } else {  
  128. 128                     try {  
  129. 129                         value = new String (fileItem.get(), charset);  
  130. 130                     } catch (UnsupportedEncodingException  e){  
  131. 131                         value = fileItem.getString();  
  132. 132                     }  
  133. 133                 }  
  134. 134   
  135. 135                 addTextParameter(name, value);  
  136. 136             } else { // fileItem is a File  
  137. 137 if (fileItem.getName() != null) {  
  138. 138                     fileItems.put(fileItem.getFieldName(), fileItem);  
  139. 139                 }  
  140. 140             }  
  141. 141         }  
  142. 142   
  143. 143         //Add the query string paramters  
  144. 144 for (Iterator it = request.getParameterMap().entrySet().iterator(); it.hasNext(); )  
  145. 145         {  
  146. 146             Map.Entry entry = (Map.Entry)it.next();  
  147. 147             String [] valuesArray = (String [])entry.getValue();  
  148. 148             for (int i = 0; i < valuesArray.length; i++)  
  149. 149             {  
  150. 150                 addTextParameter((String )entry.getKey(), valuesArray[i]);  
  151. 151             }  
  152. 152         }  
  153. 153     }  
  154. 154       
  155. 155     private void addTextParameter(String  name, String  value){  
  156. 156         if( ! parametersMap.containsKey( name ) ){  
  157. 157             String [] valuesArray = {value};  
  158. 158             parametersMap.put(name, valuesArray);  
  159. 159         }else{  
  160. 160             String [] storedValues = (String [])parametersMap.get( name );  
  161. 161             int lengthSrc = storedValues.length;  
  162. 162             String [] valuesArray = new String [lengthSrc+1];  
  163. 163             System.arraycopy(storedValues, 0, valuesArray, 0, lengthSrc);  
  164. 164             valuesArray[lengthSrc] = value;  
  165. 165             parametersMap.put(name, valuesArray);  
  166. 166         }  
  167. 167     }  
  168. 168       
  169. 169     public Enumeration getParameterNames() {  
  170. 170         if( parametersMap == null ) parseRequest();  
  171. 171           
  172. 172         return Collections.enumeration( parametersMap.keySet() );  
  173. 173     }  
  174. 174       
  175. 175     public String  getParameter(String  name) {  
  176. 176         if( parametersMap == null ) parseRequest();  
  177. 177           
  178. 178         String [] values = (String [])parametersMap.get( name );  
  179. 179         if( values == null )  
  180. 180             return null;  
  181. 181         return values[0];  
  182. 182     }  
  183. 183       
  184. 184     public String [] getParameterValues(String  name) {  
  185. 185         if( parametersMap == null ) parseRequest();  
  186. 186           
  187. 187         return (String [])parametersMap.get( name );  
  188. 188     }  
  189. 189       
  190. 190     public Map getParameterMap() {  
  191. 191         if( parametersMap == null ) parseRequest();  
  192. 192           
  193. 193         return parametersMap;  
  194. 194     }  
  195. 195       
  196. 196     // Hook for the x:inputFileUpload tag.  
  197. 197 public FileItem getFileItem(String  fieldName) {  
  198. 198         if( fileItems == null ) parseRequest();  
  199. 199           
  200. 200         return (FileItem) fileItems.get( fieldName );  
  201. 201     }  
  202. 202       
  203. 203     /** 
  204. 204      * Not used internaly by MyFaces, but provides a way to handle the uploaded files 
  205. 205      * out of MyFaces. 
  206. 206      */  
  207. 207     public Map getFileItems(){  
  208. 208         return fileItems;  
  209. 209     }  
  210. 210 }  

 

 MultipartFilter:

 

  1. /* 
  2. 2  * Copyright 2005 The Apache Software Foundation. 
  3. 3  *  
  4. 4  * Licensed under the Apache License, Version 2.0 (the "License"); 
  5. 5  * you may not use this file except in compliance with the License. 
  6. 6  * You may obtain a copy of the License at 
  7. 7  *  
  8. 8  * http://www.apache.org/licenses/LICENSE-2.0 
  9. 9  *  
  10. 10  * Unless required by applicable law or agreed to in writing, software 
  11. 11  * distributed under the License is distributed on an "AS IS" BASIS, 
  12. 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
  13. 13  * See the License for the specific language governing permissions and 
  14. 14  * limitations under the License. 
  15. 15  */  
  16. 16 package org.apache.myfaces.component.html.util;  
  17. 17   
  18. 18 import java.io.IOException ;  
  19. 19   
  20. 20 import javax.servlet.Filter ;  
  21. 21 import javax.servlet.FilterChain ;  
  22. 22 import javax.servlet.FilterConfig ;  
  23. 23 import javax.servlet.ServletException ;  
  24. 24 import javax.servlet.ServletRequest ;  
  25. 25 import javax.servlet.ServletResponse ;  
  26. 26 import javax.servlet.http.HttpServletRequest ;  
  27. 27 import javax.servlet.http.HttpServletResponse ;  
  28. 28   
  29. 29 import org.apache.commons.fileupload.FileUpload;  
  30. 30   
  31. 31   
  32. 32 /** 
  33. 33  * This filters is mandatory for the use of many components. 
  34. 34  * It handles the Multipart requests (for file upload) 
  35. 35  * It's used by the components that need javascript libraries 
  36. 36  * 
  37. 37  * @author Sylvain Vieujot (latest modification by $Author: oros $) 
  38. 38  * @author <a HREF="mailto:[email protected]" mce_HREF="mailto:[email protected]">Oliver Rossmueller </a> 
  39. 39  * @version $Revision: 1.1 $ $Date: 2005/03/20 23:16:08 $ 
  40. 40  */  
  41. 41 public class MultipartFilter implements Filter   
  42. 42 {  
  43. 43   
  44. 44     private int uploadMaxFileSize = 100 * 1024 * 1024; // 10 MB  
  45. 45   
  46. 46     private int uploadThresholdSize = 1 * 1024 * 1024; // 1 MB  
  47. 47   
  48. 48     private String  uploadRepositoryPath = null//standard temp directory  
  49. 49   
  50. 50   
  51. 51     public void init(FilterConfig  filterConfig)  
  52. 52     {  
  53. 53         uploadMaxFileSize = resolveSize(filterConfig.getInitParameter("uploadMaxFileSize"), uploadMaxFileSize);  
  54. 54         uploadThresholdSize = resolveSize(filterConfig.getInitParameter("uploadThresholdSize"), uploadThresholdSize);  
  55. 55         uploadRepositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");  
  56. 56     }  
  57. 57   
  58. 58   
  59. 59     private int resolveSize(String  param, int defaultValue)  
  60. 60     {  
  61. 61         int numberParam = defaultValue;  
  62. 62   
  63. 63         if (param != null)  
  64. 64         {  
  65. 65             param = param.toLowerCase();  
  66. 66             int factor = 1;  
  67. 67             String  number = param;  
  68. 68   
  69. 69             if (param.endsWith("g"))  
  70. 70             {  
  71. 71                 factor = 1024 * 1024 * 1024;  
  72. 72                 number = param.substring(0, param.length() - 1);  
  73. 73             } else if (param.endsWith("m"))  
  74. 74             {  
  75. 75                 factor = 1024 * 1024;  
  76. 76                 number = param.substring(0, param.length() - 1);  
  77. 77             } else if (param.endsWith("k"))  
  78. 78             {  
  79. 79                 factor = 1024;  
  80. 80                 number = param.substring(0, param.length() - 1);  
  81. 81             }  
  82. 82   
  83. 83             numberParam = Integer.parseInt(number) * factor;  
  84. 84         }  
  85. 85         return numberParam;  
  86. 86     }  
  87. 87   
  88. 88   
  89. 89     public void doFilter(ServletRequest  request, ServletResponse  response, FilterChain  chain) throws IOException , ServletException   
  90. 90     {  
  91. 91         if (!(response instanceof HttpServletResponse ))  
  92. 92         {  
  93. 93             chain.doFilter(request, response);  
  94. 94             return;  
  95. 95         }  
  96. 96   
  97. 97         HttpServletRequest  httpRequest = (HttpServletRequest ) request;  
  98. 98   
  99. 99         // For multipart/form-data requests  
  100. 100 if (FileUpload.isMultipartContent(httpRequest))  
  101. 101         {  
  102. 102             chain.doFilter(new MultipartRequestWrapper(httpRequest, uploadMaxFileSize, uploadThresholdSize, uploadRepositoryPath), response);  
  103. 103         } else  
  104. 104         {  
  105. 105             chain.doFilter(request, response);  
  106. 106         }  
  107. 107     }  
  108. 108   
  109. 109   
  110. 110     public void destroy()  
  111. 111     {  
  112. 112         // NoOp  
  113. 113 }  
  114. 114 }  

 

你可能感兴趣的:(JSF,JSF上传,JSF文件上传)