1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.xchain.framework.servlet;
17
18 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
19 import org.apache.commons.fileupload.servlet.ServletFileUpload;
20 import org.apache.commons.fileupload.FileItem;
21 import org.apache.commons.fileupload.FileUploadException;
22
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 import javax.servlet.http.HttpServletRequestWrapper;
27 import javax.servlet.http.HttpServletRequest;
28
29 import java.util.List;
30 import java.util.Map;
31 import java.util.HashMap;
32 import java.util.ArrayList;
33 import java.util.Iterator;
34 import java.util.Enumeration;
35
36 import java.io.File;
37 import java.lang.reflect.Array;
38
39
40
41
42
43
44
45
46
47
48
49 public class MultipartFormDataServletRequest
50 extends HttpServletRequestWrapper {
51
52 public static Logger log = LoggerFactory.getLogger(MultipartFormDataServletRequest.class);
53
54 private Map<String, String[]> parameterMap = new HashMap<String, String[]>();
55 private Map<String, FileItem[]> fileItemMap = new HashMap<String, FileItem[]>();
56
57 public MultipartFormDataServletRequest(HttpServletRequest request, long maxSize, int sizeThreshold, String repositoryPath)
58 throws FileUploadException
59 {
60 super(request);
61
62
63 DiskFileItemFactory factory = createDiskFileItemFactory(sizeThreshold, repositoryPath);
64 ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
65
66 servletFileUpload.setSizeMax(maxSize);
67
68
69 Iterator<FileItem> fileItemIterator = servletFileUpload.parseRequest(request).iterator();
70
71
72 Map<String, List<String>> parameterMap = new HashMap<String, List<String>>();
73 Map<String, List<FileItem>> fileItemMap = new HashMap<String, List<FileItem>>();
74
75
76 while( fileItemIterator.hasNext() ) {
77 FileItem fileItem = fileItemIterator.next();
78 if (fileItem.isFormField()) {
79 putListMapValue(parameterMap, fileItem.getFieldName(), fileItem.getString());
80 } else {
81 putListMapValue(fileItemMap, fileItem.getFieldName(), fileItem);
82 }
83 }
84
85
86 convertListMapToArrayMap(parameterMap, this.parameterMap, String.class);
87 convertListMapToArrayMap(fileItemMap, this.fileItemMap, FileItem.class);
88
89 if( log.isDebugEnabled() ) {
90 logFileItemMap();
91 }
92
93 }
94
95 public FileItem getFileItem( String name )
96 {
97 FileItem fileItem = null;
98 FileItem[] fileItemArray = (FileItem[])fileItemMap.get(name);
99
100 if( fileItemArray != null )
101 fileItem = fileItemArray[0];
102
103 return fileItem;
104 }
105
106 public Enumeration<String> getFileItemNames()
107 {
108 return new IteratorEnumeration<String>(fileItemMap.keySet().iterator());
109 }
110
111 public Map<String, FileItem[]> getFileItemMap()
112 {
113 return fileItemMap;
114 }
115
116 public FileItem[] getFileItemValues( String name )
117 {
118 return (FileItem[])fileItemMap.get(name);
119 }
120
121 public String getParameter( String name )
122 {
123 String parameter = null;
124 String[] parameterList = (String[])parameterMap.get(name);
125
126 if( parameterList != null && parameterList.length > 0 ) {
127 parameter = parameterList[0];
128 }
129
130 return parameter;
131 }
132
133 public Enumeration<String> getParameterNames() { return new IteratorEnumeration<String>(parameterMap.keySet().iterator()); }
134
135 public Map<String, String[]> getParameterMap() { return parameterMap; }
136
137 public String[] getParameterValues( String name ) { return (String[])parameterMap.get(name); }
138
139 private static <K,V> Map<K, V[]> convertListMapToArrayMap(Map<K, List<V>> listMap, Map<K, V[]> arrayMap, Class<V> elementType) {
140 if( arrayMap == null )
141 arrayMap = new HashMap<K, V[]>();
142 for( Map.Entry<K, List<V>> e : listMap.entrySet() ) {
143 V[] valueArray = (V[]) Array.newInstance(elementType, e.getValue().size());
144 arrayMap.put(e.getKey(), e.getValue().toArray(valueArray));
145 }
146 return arrayMap;
147 }
148
149 private static <K, V> void putListMapValue( Map<K, List<V>> map, K key, V value )
150 {
151 List<V> valueArray = map.get(key);
152
153 if( valueArray == null ) {
154 valueArray = new ArrayList<V>();
155 map.put(key, valueArray);
156 }
157 valueArray.add(value);
158 }
159
160 private static DiskFileItemFactory createDiskFileItemFactory( int sizeThreshold, String repositoryPath ) throws FileUploadException {
161 DiskFileItemFactory factory = new DiskFileItemFactory();
162
163
164 File repository = new File(repositoryPath);
165 factory.setRepository(repository);
166
167
168 factory.setSizeThreshold(sizeThreshold);
169
170
171 if( repository.exists() ) {
172 if( !repository.isDirectory() ) {
173 throw new FileUploadException("Cannot upload files because the specified temporary "
174 + "directory is of type file. (" + repository.getAbsolutePath() + ")");
175 }
176 } else if( !repository.mkdir() ) {
177 throw new FileUploadException("Cannot upload files because the specified temporary "
178 + " does not exist, and attempts to create it have failed. ("
179 + repository.getAbsolutePath() + ")");
180
181 }
182 return factory;
183 }
184
185 protected void logFileItemMap()
186 {
187 log.debug("File item map has "+fileItemMap.keySet().size()+" keys.");
188 Iterator<Map.Entry<String, FileItem[]>> entryIterator = fileItemMap.entrySet().iterator();
189 while( entryIterator.hasNext() ) {
190 Map.Entry<String, FileItem[]> entry = entryIterator.next();
191 String key = entry.getKey();
192 FileItem[] fileItems = entry.getValue();
193
194 log.debug("Key '"+key+"' has "+fileItems.length+" entries.");
195
196 for( int i = 0; i < fileItems.length; i++ ) {
197 log.debug("Name='"+fileItems[i].getName()+"', size="+fileItems[i].getSize()+", content-type='"+fileItems[i].getContentType()+"'");
198 }
199 }
200 }
201 }
202
203 class IteratorEnumeration<T>
204 implements Enumeration<T>
205 {
206 Iterator<T> wrappedIterator = null;
207 public IteratorEnumeration( Iterator<T> wrappedIterator ) { this.wrappedIterator = wrappedIterator; }
208 public boolean hasMoreElements() { return wrappedIterator.hasNext(); }
209 public T nextElement() { return wrappedIterator.next(); }
210 }