39
39
import org .springframework .stereotype .Controller ;
40
40
import org .springframework .test .web .servlet .MockMvc ;
41
41
import org .springframework .ui .Model ;
42
+ import org .springframework .util .StreamUtils ;
43
+ import org .springframework .validation .BindException ;
44
+ import org .springframework .validation .BindingResult ;
42
45
import org .springframework .web .bind .annotation .RequestMapping ;
43
46
import org .springframework .web .bind .annotation .RequestMethod ;
44
47
import org .springframework .web .bind .annotation .RequestParam ;
56
59
/**
57
60
* @author Rossen Stoyanchev
58
61
* @author Juergen Hoeller
62
+ * @author Jaebin Joo
59
63
*/
60
64
public class MultipartControllerTests {
61
65
@@ -225,7 +229,7 @@ public void multipartRequestWithOptionalFileListNotPresent() throws Exception {
225
229
}
226
230
227
231
@ Test
228
- public void multipartRequestWithServletParts () throws Exception {
232
+ public void multipartRequestWithParts_resolvesMultipartFileArguments () throws Exception {
229
233
byte [] fileContent = "bar" .getBytes (StandardCharsets .UTF_8 );
230
234
MockPart filePart = new MockPart ("file" , "orig" , fileContent );
231
235
@@ -240,6 +244,50 @@ public void multipartRequestWithServletParts() throws Exception {
240
244
.andExpect (model ().attribute ("jsonContent" , Collections .singletonMap ("name" , "yeeeah" )));
241
245
}
242
246
247
+ @ Test
248
+ public void multipartRequestWithParts_resolvesPartArguments () throws Exception {
249
+ byte [] fileContent = "bar" .getBytes (StandardCharsets .UTF_8 );
250
+ MockPart filePart = new MockPart ("file" , "orig" , fileContent );
251
+
252
+ byte [] json = "{\" name\" :\" yeeeah\" }" .getBytes (StandardCharsets .UTF_8 );
253
+ MockPart jsonPart = new MockPart ("json" , json );
254
+ jsonPart .getHeaders ().setContentType (MediaType .APPLICATION_JSON );
255
+
256
+ standaloneSetup (new MultipartController ()).build ()
257
+ .perform (multipart ("/part" ).part (filePart ).part (jsonPart ))
258
+ .andExpect (status ().isFound ())
259
+ .andExpect (model ().attribute ("fileContent" , fileContent ))
260
+ .andExpect (model ().attribute ("jsonContent" , Collections .singletonMap ("name" , "yeeeah" )));
261
+ }
262
+
263
+ @ Test
264
+ public void multipartRequestWithParts_resolvesMultipartFileProperties () throws Exception {
265
+ byte [] fileContent = "bar" .getBytes (StandardCharsets .UTF_8 );
266
+ MockPart filePart = new MockPart ("file" , "orig" , fileContent );
267
+
268
+ standaloneSetup (new MultipartController ()).build ()
269
+ .perform (multipart ("/multipartfileproperty" ).part (filePart ))
270
+ .andExpect (status ().isFound ())
271
+ .andExpect (model ().attribute ("fileContent" , fileContent ));
272
+ }
273
+
274
+ @ Test
275
+ public void multipartRequestWithParts_cannotResolvePartProperties () throws Exception {
276
+ byte [] fileContent = "bar" .getBytes (StandardCharsets .UTF_8 );
277
+ MockPart filePart = new MockPart ("file" , "orig" , fileContent );
278
+
279
+ Exception exception = standaloneSetup (new MultipartController ()).build ()
280
+ .perform (multipart ("/partproperty" ).part (filePart ))
281
+ .andExpect (status ().is4xxClientError ())
282
+ .andReturn ()
283
+ .getResolvedException ();
284
+
285
+ assertThat (exception ).isNotNull ();
286
+ assertThat (exception ).isInstanceOf (BindException .class );
287
+ assertThat (((BindException ) exception ).getFieldError ("file" ))
288
+ .as ("MultipartRequest would not bind Part properties." ).isNotNull ();
289
+ }
290
+
243
291
@ Test // SPR-13317
244
292
public void multipartRequestWrapped () throws Exception {
245
293
byte [] json = "{\" name\" :\" yeeeah\" }" .getBytes (StandardCharsets .UTF_8 );
@@ -343,10 +391,13 @@ public String processOptionalFileList(@RequestParam Optional<List<MultipartFile>
343
391
}
344
392
345
393
@ RequestMapping (value = "/part" , method = RequestMethod .POST )
346
- public String processPart (@ RequestParam Part part ,
394
+ public String processPart (@ RequestPart Part file ,
347
395
@ RequestPart Map <String , String > json , Model model ) throws IOException {
348
396
349
- model .addAttribute ("fileContent" , part .getInputStream ());
397
+ if (file != null ) {
398
+ byte [] content = StreamUtils .copyToByteArray (file .getInputStream ());
399
+ model .addAttribute ("fileContent" , content );
400
+ }
350
401
model .addAttribute ("jsonContent" , json );
351
402
352
403
return "redirect:/index" ;
@@ -357,8 +408,60 @@ public String processMultipart(@RequestPart Map<String, String> json, Model mode
357
408
model .addAttribute ("json" , json );
358
409
return "redirect:/index" ;
359
410
}
411
+
412
+ @ RequestMapping (value = "/multipartfileproperty" , method = RequestMethod .POST )
413
+ public String processMultipartFileBean (MultipartFileBean multipartFileBean , Model model , BindingResult bindingResult )
414
+ throws IOException {
415
+
416
+ if (!bindingResult .hasErrors ()) {
417
+ MultipartFile file = multipartFileBean .getFile ();
418
+ if (file != null ) {
419
+ model .addAttribute ("fileContent" , file .getBytes ());
420
+ }
421
+ }
422
+ return "redirect:/index" ;
423
+ }
424
+
425
+ @ RequestMapping (value = "/partproperty" , method = RequestMethod .POST )
426
+ public String processPartBean (PartBean partBean , Model model , BindingResult bindingResult )
427
+ throws IOException {
428
+
429
+ if (!bindingResult .hasErrors ()) {
430
+ Part file = partBean .getFile ();
431
+ if (file != null ) {
432
+ byte [] content = StreamUtils .copyToByteArray (file .getInputStream ());
433
+ model .addAttribute ("fileContent" , content );
434
+ }
435
+ }
436
+ return "redirect:/index" ;
437
+ }
360
438
}
361
439
440
+ private static class MultipartFileBean {
441
+
442
+ private MultipartFile file ;
443
+
444
+ public MultipartFile getFile () {
445
+ return file ;
446
+ }
447
+
448
+ public void setFile (MultipartFile file ) {
449
+ this .file = file ;
450
+ }
451
+ }
452
+
453
+ private static class PartBean {
454
+
455
+ private Part file ;
456
+
457
+ public Part getFile () {
458
+ return file ;
459
+ }
460
+
461
+ public void setFile (Part file ) {
462
+ this .file = file ;
463
+ }
464
+ }
362
465
363
466
private static class RequestWrappingFilter extends OncePerRequestFilter {
364
467
0 commit comments