PageRenderTime 27ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/springframework-3.0.5/projects/org.springframework.web/src/test/java/org/springframework/web/multipart/commons/CommonsMultipartResolverTests.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 532 lines | 434 code | 78 blank | 20 comment | 12 complexity | aa0d406d1c30b0907ac560c7411215d0 MD5 | raw file
  1. /*
  2. * Copyright 2002-2010 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.web.multipart.commons;
  17. import java.io.ByteArrayInputStream;
  18. import java.io.File;
  19. import java.io.IOException;
  20. import java.io.InputStream;
  21. import java.io.OutputStream;
  22. import java.io.UnsupportedEncodingException;
  23. import java.util.ArrayList;
  24. import java.util.Arrays;
  25. import java.util.Enumeration;
  26. import java.util.HashSet;
  27. import java.util.Iterator;
  28. import java.util.List;
  29. import java.util.Map;
  30. import java.util.Set;
  31. import javax.servlet.FilterChain;
  32. import javax.servlet.ServletException;
  33. import javax.servlet.ServletRequest;
  34. import javax.servlet.ServletResponse;
  35. import javax.servlet.http.HttpServletRequest;
  36. import javax.servlet.http.HttpServletResponse;
  37. import org.apache.commons.fileupload.FileItem;
  38. import org.apache.commons.fileupload.FileItemFactory;
  39. import org.apache.commons.fileupload.FileUpload;
  40. import org.apache.commons.fileupload.servlet.ServletFileUpload;
  41. import static org.junit.Assert.*;
  42. import org.junit.Test;
  43. import org.springframework.beans.MutablePropertyValues;
  44. import org.springframework.mock.web.MockFilterConfig;
  45. import org.springframework.mock.web.MockHttpServletRequest;
  46. import org.springframework.mock.web.MockHttpServletResponse;
  47. import org.springframework.mock.web.MockServletContext;
  48. import org.springframework.mock.web.PassThroughFilterChain;
  49. import org.springframework.util.MultiValueMap;
  50. import org.springframework.web.bind.ServletRequestDataBinder;
  51. import org.springframework.web.context.WebApplicationContext;
  52. import org.springframework.web.context.support.StaticWebApplicationContext;
  53. import org.springframework.web.multipart.MultipartFile;
  54. import org.springframework.web.multipart.MultipartHttpServletRequest;
  55. import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
  56. import org.springframework.web.multipart.support.MultipartFilter;
  57. import org.springframework.web.multipart.support.StringMultipartFileEditor;
  58. import org.springframework.web.util.WebUtils;
  59. /**
  60. * @author Juergen Hoeller
  61. * @author Arjen Poutsma
  62. * @since 08.10.2003
  63. */
  64. public class CommonsMultipartResolverTests {
  65. @Test
  66. public void withApplicationContext() throws Exception {
  67. doTestWithApplicationContext(false);
  68. }
  69. @Test
  70. public void withApplicationContextAndLazyResolution() throws Exception {
  71. doTestWithApplicationContext(true);
  72. }
  73. private void doTestWithApplicationContext(boolean lazy) throws Exception {
  74. StaticWebApplicationContext wac = new StaticWebApplicationContext();
  75. wac.setServletContext(new MockServletContext());
  76. wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp"));
  77. wac.refresh();
  78. MockCommonsMultipartResolver resolver = new MockCommonsMultipartResolver();
  79. resolver.setMaxUploadSize(1000);
  80. resolver.setMaxInMemorySize(100);
  81. resolver.setDefaultEncoding("enc");
  82. if (lazy) {
  83. resolver.setResolveLazily(false);
  84. }
  85. resolver.setServletContext(wac.getServletContext());
  86. assertEquals(1000, resolver.getFileUpload().getSizeMax());
  87. assertEquals(100, resolver.getFileItemFactory().getSizeThreshold());
  88. assertEquals("enc", resolver.getFileUpload().getHeaderEncoding());
  89. assertTrue(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp"));
  90. MockHttpServletRequest originalRequest = new MockHttpServletRequest();
  91. originalRequest.setMethod("POST");
  92. originalRequest.setContentType("multipart/form-data");
  93. originalRequest.addHeader("Content-type", "multipart/form-data");
  94. originalRequest.addParameter("getField", "getValue");
  95. assertTrue(resolver.isMultipart(originalRequest));
  96. MultipartHttpServletRequest request = resolver.resolveMultipart(originalRequest);
  97. doTestParameters(request);
  98. doTestFiles(request);
  99. doTestBinding(resolver, originalRequest, request);
  100. }
  101. private void doTestParameters(MultipartHttpServletRequest request) {
  102. Set<String> parameterNames = new HashSet<String>();
  103. Enumeration parameterEnum = request.getParameterNames();
  104. while (parameterEnum.hasMoreElements()) {
  105. parameterNames.add((String) parameterEnum.nextElement());
  106. }
  107. assertEquals(3, parameterNames.size());
  108. assertTrue(parameterNames.contains("field3"));
  109. assertTrue(parameterNames.contains("field4"));
  110. assertTrue(parameterNames.contains("getField"));
  111. assertEquals("value3", request.getParameter("field3"));
  112. List parameterValues = Arrays.asList(request.getParameterValues("field3"));
  113. assertEquals(1, parameterValues.size());
  114. assertTrue(parameterValues.contains("value3"));
  115. assertEquals("value4", request.getParameter("field4"));
  116. parameterValues = Arrays.asList(request.getParameterValues("field4"));
  117. assertEquals(2, parameterValues.size());
  118. assertTrue(parameterValues.contains("value4"));
  119. assertTrue(parameterValues.contains("value5"));
  120. assertEquals("value4", request.getParameter("field4"));
  121. assertEquals("getValue", request.getParameter("getField"));
  122. List<String> parameterMapKeys = new ArrayList<String>();
  123. List<Object> parameterMapValues = new ArrayList<Object>();
  124. for (Object o : request.getParameterMap().keySet()) {
  125. String key = (String) o;
  126. parameterMapKeys.add(key);
  127. parameterMapValues.add(request.getParameterMap().get(key));
  128. }
  129. assertEquals(3, parameterMapKeys.size());
  130. assertEquals(3, parameterMapValues.size());
  131. int field3Index = parameterMapKeys.indexOf("field3");
  132. int field4Index = parameterMapKeys.indexOf("field4");
  133. int getFieldIndex = parameterMapKeys.indexOf("getField");
  134. assertTrue(field3Index != -1);
  135. assertTrue(field4Index != -1);
  136. assertTrue(getFieldIndex != -1);
  137. parameterValues = Arrays.asList((String[]) parameterMapValues.get(field3Index));
  138. assertEquals(1, parameterValues.size());
  139. assertTrue(parameterValues.contains("value3"));
  140. parameterValues = Arrays.asList((String[]) parameterMapValues.get(field4Index));
  141. assertEquals(2, parameterValues.size());
  142. assertTrue(parameterValues.contains("value4"));
  143. assertTrue(parameterValues.contains("value5"));
  144. parameterValues = Arrays.asList((String[]) parameterMapValues.get(getFieldIndex));
  145. assertEquals(1, parameterValues.size());
  146. assertTrue(parameterValues.contains("getValue"));
  147. }
  148. private void doTestFiles(MultipartHttpServletRequest request) throws IOException {
  149. Set<String> fileNames = new HashSet<String>();
  150. Iterator fileIter = request.getFileNames();
  151. while (fileIter.hasNext()) {
  152. fileNames.add((String) fileIter.next());
  153. }
  154. assertEquals(3, fileNames.size());
  155. assertTrue(fileNames.contains("field1"));
  156. assertTrue(fileNames.contains("field2"));
  157. assertTrue(fileNames.contains("field2x"));
  158. CommonsMultipartFile file1 = (CommonsMultipartFile) request.getFile("field1");
  159. CommonsMultipartFile file2 = (CommonsMultipartFile) request.getFile("field2");
  160. CommonsMultipartFile file2x = (CommonsMultipartFile) request.getFile("field2x");
  161. Map<String, MultipartFile> fileMap = request.getFileMap();
  162. assertEquals(3, fileMap.size());
  163. assertTrue(fileMap.containsKey("field1"));
  164. assertTrue(fileMap.containsKey("field2"));
  165. assertTrue(fileMap.containsKey("field2x"));
  166. assertEquals(file1, fileMap.get("field1"));
  167. assertEquals(file2, fileMap.get("field2"));
  168. assertEquals(file2x, fileMap.get("field2x"));
  169. MultiValueMap<String, MultipartFile> multiFileMap = request.getMultiFileMap();
  170. assertEquals(3, multiFileMap.size());
  171. assertTrue(multiFileMap.containsKey("field1"));
  172. assertTrue(multiFileMap.containsKey("field2"));
  173. assertTrue(multiFileMap.containsKey("field2x"));
  174. List<MultipartFile> field1Files = multiFileMap.get("field1");
  175. assertEquals(2, field1Files.size());
  176. assertTrue(field1Files.contains(file1));
  177. assertEquals(file1, multiFileMap.getFirst("field1"));
  178. assertEquals(file2, multiFileMap.getFirst("field2"));
  179. assertEquals(file2x, multiFileMap.getFirst("field2x"));
  180. assertEquals("type1", file1.getContentType());
  181. assertEquals("type2", file2.getContentType());
  182. assertEquals("type2", file2x.getContentType());
  183. assertEquals("field1.txt", file1.getOriginalFilename());
  184. assertEquals("field2.txt", file2.getOriginalFilename());
  185. assertEquals("field2x.txt", file2x.getOriginalFilename());
  186. assertEquals("text1", new String(file1.getBytes()));
  187. assertEquals("text2", new String(file2.getBytes()));
  188. assertEquals(5, file1.getSize());
  189. assertEquals(5, file2.getSize());
  190. assertTrue(file1.getInputStream() instanceof ByteArrayInputStream);
  191. assertTrue(file2.getInputStream() instanceof ByteArrayInputStream);
  192. File transfer1 = new File("C:/transfer1");
  193. file1.transferTo(transfer1);
  194. File transfer2 = new File("C:/transfer2");
  195. file2.transferTo(transfer2);
  196. assertEquals(transfer1, ((MockFileItem) file1.getFileItem()).writtenFile);
  197. assertEquals(transfer2, ((MockFileItem) file2.getFileItem()).writtenFile);
  198. }
  199. private void doTestBinding(MockCommonsMultipartResolver resolver, MockHttpServletRequest originalRequest,
  200. MultipartHttpServletRequest request) throws UnsupportedEncodingException {
  201. MultipartTestBean1 mtb1 = new MultipartTestBean1();
  202. assertEquals(null, mtb1.getField1());
  203. assertEquals(null, mtb1.getField2());
  204. ServletRequestDataBinder binder = new ServletRequestDataBinder(mtb1, "mybean");
  205. binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
  206. binder.bind(request);
  207. List<MultipartFile> file1List = request.getFiles("field1");
  208. CommonsMultipartFile file1a = (CommonsMultipartFile) file1List.get(0);
  209. CommonsMultipartFile file1b = (CommonsMultipartFile) file1List.get(1);
  210. CommonsMultipartFile file2 = (CommonsMultipartFile) request.getFile("field2");
  211. assertEquals(file1a, mtb1.getField1()[0]);
  212. assertEquals(file1b, mtb1.getField1()[1]);
  213. assertEquals(new String(file2.getBytes()), new String(mtb1.getField2()));
  214. MultipartTestBean2 mtb2 = new MultipartTestBean2();
  215. assertEquals(null, mtb2.getField1());
  216. assertEquals(null, mtb2.getField2());
  217. binder = new ServletRequestDataBinder(mtb2, "mybean");
  218. binder.registerCustomEditor(String.class, "field1", new StringMultipartFileEditor());
  219. binder.registerCustomEditor(String.class, "field2", new StringMultipartFileEditor("UTF-16"));
  220. binder.bind(request);
  221. assertEquals(new String(file1a.getBytes()), mtb2.getField1()[0]);
  222. assertEquals(new String(file1b.getBytes()), mtb2.getField1()[1]);
  223. assertEquals(new String(file2.getBytes(), "UTF-16"), mtb2.getField2());
  224. resolver.cleanupMultipart(request);
  225. assertTrue(((MockFileItem) file1a.getFileItem()).deleted);
  226. assertTrue(((MockFileItem) file1b.getFileItem()).deleted);
  227. assertTrue(((MockFileItem) file2.getFileItem()).deleted);
  228. resolver.setEmpty(true);
  229. request = resolver.resolveMultipart(originalRequest);
  230. binder.setBindEmptyMultipartFiles(false);
  231. String firstBound = mtb2.getField2();
  232. binder.bind(request);
  233. assertTrue(mtb2.getField2().length() > 0);
  234. assertEquals(firstBound, mtb2.getField2());
  235. request = resolver.resolveMultipart(originalRequest);
  236. binder.setBindEmptyMultipartFiles(true);
  237. binder.bind(request);
  238. assertTrue(mtb2.getField2().length() == 0);
  239. }
  240. @Test
  241. public void withServletContextAndFilter() throws Exception {
  242. StaticWebApplicationContext wac = new StaticWebApplicationContext();
  243. wac.setServletContext(new MockServletContext());
  244. wac.registerSingleton("filterMultipartResolver", MockCommonsMultipartResolver.class, new MutablePropertyValues());
  245. wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp"));
  246. wac.refresh();
  247. wac.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
  248. CommonsMultipartResolver resolver = new CommonsMultipartResolver(wac.getServletContext());
  249. assertTrue(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp"));
  250. MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
  251. filterConfig.addInitParameter("class", "notWritable");
  252. filterConfig.addInitParameter("unknownParam", "someValue");
  253. final MultipartFilter filter = new MultipartFilter();
  254. filter.init(filterConfig);
  255. final List<MultipartFile> files = new ArrayList<MultipartFile>();
  256. final FilterChain filterChain = new FilterChain() {
  257. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
  258. MultipartHttpServletRequest request = (MultipartHttpServletRequest) servletRequest;
  259. files.addAll(request.getFileMap().values());
  260. }
  261. };
  262. FilterChain filterChain2 = new PassThroughFilterChain(filter, filterChain);
  263. MockHttpServletRequest originalRequest = new MockHttpServletRequest();
  264. MockHttpServletResponse response = new MockHttpServletResponse();
  265. originalRequest.setMethod("POST");
  266. originalRequest.setContentType("multipart/form-data");
  267. originalRequest.addHeader("Content-type", "multipart/form-data");
  268. filter.doFilter(originalRequest, response, filterChain2);
  269. CommonsMultipartFile file1 = (CommonsMultipartFile) files.get(0);
  270. CommonsMultipartFile file2 = (CommonsMultipartFile) files.get(1);
  271. assertTrue(((MockFileItem) file1.getFileItem()).deleted);
  272. assertTrue(((MockFileItem) file2.getFileItem()).deleted);
  273. }
  274. @Test
  275. public void withServletContextAndFilterWithCustomBeanName() throws Exception {
  276. StaticWebApplicationContext wac = new StaticWebApplicationContext();
  277. wac.setServletContext(new MockServletContext());
  278. wac.refresh();
  279. wac.registerSingleton("myMultipartResolver", MockCommonsMultipartResolver.class, new MutablePropertyValues());
  280. wac.getServletContext().setAttribute(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File("mytemp"));
  281. wac.getServletContext().setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);
  282. CommonsMultipartResolver resolver = new CommonsMultipartResolver(wac.getServletContext());
  283. assertTrue(resolver.getFileItemFactory().getRepository().getAbsolutePath().endsWith("mytemp"));
  284. MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
  285. filterConfig.addInitParameter("multipartResolverBeanName", "myMultipartResolver");
  286. final List<MultipartFile> files = new ArrayList<MultipartFile>();
  287. FilterChain filterChain = new FilterChain() {
  288. public void doFilter(ServletRequest originalRequest, ServletResponse response) {
  289. if (originalRequest instanceof MultipartHttpServletRequest) {
  290. MultipartHttpServletRequest request = (MultipartHttpServletRequest) originalRequest;
  291. files.addAll(request.getFileMap().values());
  292. }
  293. }
  294. };
  295. MultipartFilter filter = new MultipartFilter() {
  296. private boolean invoked = false;
  297. @Override
  298. protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
  299. FilterChain filterChain) throws ServletException, IOException {
  300. super.doFilterInternal(request, response, filterChain);
  301. super.doFilterInternal(request, response, filterChain);
  302. if (invoked) {
  303. throw new ServletException("Should not have been invoked twice");
  304. }
  305. invoked = true;
  306. }
  307. };
  308. filter.init(filterConfig);
  309. MockHttpServletRequest originalRequest = new MockHttpServletRequest();
  310. originalRequest.setMethod("POST");
  311. originalRequest.setContentType("multipart/form-data");
  312. originalRequest.addHeader("Content-type", "multipart/form-data");
  313. HttpServletResponse response = new MockHttpServletResponse();
  314. filter.doFilter(originalRequest, response, filterChain);
  315. CommonsMultipartFile file1 = (CommonsMultipartFile) files.get(0);
  316. CommonsMultipartFile file2 = (CommonsMultipartFile) files.get(1);
  317. assertTrue(((MockFileItem) file1.getFileItem()).deleted);
  318. assertTrue(((MockFileItem) file2.getFileItem()).deleted);
  319. }
  320. public static class MockCommonsMultipartResolver extends CommonsMultipartResolver {
  321. private boolean empty;
  322. protected void setEmpty(boolean empty) {
  323. this.empty = empty;
  324. }
  325. @Override
  326. protected FileUpload newFileUpload(FileItemFactory fileItemFactory) {
  327. return new ServletFileUpload() {
  328. @Override
  329. public List parseRequest(HttpServletRequest request) {
  330. if (request instanceof MultipartHttpServletRequest) {
  331. throw new IllegalStateException("Already a multipart request");
  332. }
  333. List<FileItem> fileItems = new ArrayList<FileItem>();
  334. MockFileItem fileItem1 = new MockFileItem(
  335. "field1", "type1", empty ? "" : "field1.txt", empty ? "" : "text1");
  336. MockFileItem fileItem1x = new MockFileItem(
  337. "field1", "type1", empty ? "" : "field1.txt", empty ? "" : "text1");
  338. MockFileItem fileItem2 = new MockFileItem(
  339. "field2", "type2", empty ? "" : "C:/field2.txt", empty ? "" : "text2");
  340. MockFileItem fileItem2x = new MockFileItem(
  341. "field2x", "type2", empty ? "" : "C:\\field2x.txt", empty ? "" : "text2");
  342. MockFileItem fileItem3 = new MockFileItem("field3", null, null, "value3");
  343. MockFileItem fileItem4 = new MockFileItem("field4", "text/html; charset=iso-8859-1", null, "value4");
  344. MockFileItem fileItem5 = new MockFileItem("field4", null, null, "value5");
  345. fileItems.add(fileItem1);
  346. fileItems.add(fileItem1x);
  347. fileItems.add(fileItem2);
  348. fileItems.add(fileItem2x);
  349. fileItems.add(fileItem3);
  350. fileItems.add(fileItem4);
  351. fileItems.add(fileItem5);
  352. return fileItems;
  353. }
  354. };
  355. }
  356. }
  357. private static class MockFileItem implements FileItem {
  358. private String fieldName;
  359. private String contentType;
  360. private String name;
  361. private String value;
  362. private File writtenFile;
  363. private boolean deleted;
  364. public MockFileItem(String fieldName, String contentType, String name, String value) {
  365. this.fieldName = fieldName;
  366. this.contentType = contentType;
  367. this.name = name;
  368. this.value = value;
  369. }
  370. public InputStream getInputStream() throws IOException {
  371. return new ByteArrayInputStream(value.getBytes());
  372. }
  373. public String getContentType() {
  374. return contentType;
  375. }
  376. public String getName() {
  377. return name;
  378. }
  379. public boolean isInMemory() {
  380. return true;
  381. }
  382. public long getSize() {
  383. return value.length();
  384. }
  385. public byte[] get() {
  386. return value.getBytes();
  387. }
  388. public String getString(String encoding) throws UnsupportedEncodingException {
  389. return new String(get(), encoding);
  390. }
  391. public String getString() {
  392. return value;
  393. }
  394. public void write(File file) throws Exception {
  395. this.writtenFile = file;
  396. }
  397. public File getWrittenFile() {
  398. return writtenFile;
  399. }
  400. public void delete() {
  401. this.deleted = true;
  402. }
  403. public boolean isDeleted() {
  404. return deleted;
  405. }
  406. public String getFieldName() {
  407. return fieldName;
  408. }
  409. public void setFieldName(String s) {
  410. this.fieldName = s;
  411. }
  412. public boolean isFormField() {
  413. return (this.name == null);
  414. }
  415. public void setFormField(boolean b) {
  416. throw new UnsupportedOperationException();
  417. }
  418. public OutputStream getOutputStream() throws IOException {
  419. throw new UnsupportedOperationException();
  420. }
  421. }
  422. public class MultipartTestBean1 {
  423. private MultipartFile[] field1;
  424. private byte[] field2;
  425. public void setField1(MultipartFile[] field1) {
  426. this.field1 = field1;
  427. }
  428. public MultipartFile[] getField1() {
  429. return field1;
  430. }
  431. public void setField2(byte[] field2) {
  432. this.field2 = field2;
  433. }
  434. public byte[] getField2() {
  435. return field2;
  436. }
  437. }
  438. public class MultipartTestBean2 {
  439. private String[] field1;
  440. private String field2;
  441. public void setField1(String[] field1) {
  442. this.field1 = field1;
  443. }
  444. public String[] getField1() {
  445. return field1;
  446. }
  447. public void setField2(String field2) {
  448. this.field2 = field2;
  449. }
  450. public String getField2() {
  451. return field2;
  452. }
  453. }
  454. }