|
38 | 38 | import org.springframework.stereotype.Controller;
|
39 | 39 | import org.springframework.test.web.servlet.MockMvc;
|
40 | 40 | import org.springframework.ui.Model;
|
| 41 | +import org.springframework.util.StreamUtils; |
41 | 42 | import org.springframework.web.bind.annotation.RequestMapping;
|
42 | 43 | import org.springframework.web.bind.annotation.RequestMethod;
|
43 | 44 | import org.springframework.web.bind.annotation.RequestParam;
|
@@ -239,6 +240,38 @@ public void multipartRequestWithServletParts() throws Exception {
|
239 | 240 | .andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah")));
|
240 | 241 | }
|
241 | 242 |
|
| 243 | + @Test |
| 244 | + public void multipartRequestWithServletPartsForPartAttribute() throws Exception { |
| 245 | + byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
| 246 | + MockPart filePart = new MockPart("file", "orig", fileContent); |
| 247 | + |
| 248 | + byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
| 249 | + MockPart jsonPart = new MockPart("json", json); |
| 250 | + jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON); |
| 251 | + |
| 252 | + standaloneSetup(new MultipartController()).build() |
| 253 | + .perform(multipart("/partattr").part(filePart).part(jsonPart)) |
| 254 | + .andExpect(status().isFound()) |
| 255 | + .andExpect(model().attribute("fileContent", fileContent)) |
| 256 | + .andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
| 257 | + } |
| 258 | + |
| 259 | + @Test |
| 260 | + public void multipartRequestWithServletPartsForMultipartFileAttribute() throws Exception { |
| 261 | + byte[] fileContent = "foo".getBytes(StandardCharsets.UTF_8); |
| 262 | + MockPart filePart = new MockPart("file", "orig", fileContent); |
| 263 | + |
| 264 | + byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
| 265 | + MockPart jsonPart = new MockPart("json", json); |
| 266 | + jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON); |
| 267 | + |
| 268 | + standaloneSetup(new MultipartController()).build() |
| 269 | + .perform(multipart("/multipartfileattr").part(filePart).part(jsonPart)) |
| 270 | + .andExpect(status().isFound()) |
| 271 | + .andExpect(model().attribute("fileContent", fileContent)) |
| 272 | + .andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
| 273 | + } |
| 274 | + |
242 | 275 | @Test // SPR-13317
|
243 | 276 | public void multipartRequestWrapped() throws Exception {
|
244 | 277 | byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8);
|
@@ -341,29 +374,79 @@ public String processOptionalFileList(@RequestParam Optional<List<MultipartFile>
|
341 | 374 | return "redirect:/index";
|
342 | 375 | }
|
343 | 376 |
|
344 |
| - @RequestMapping(value = "/part", method = RequestMethod.POST) |
345 |
| - public String processPart(@RequestParam Part part, |
346 |
| - @RequestPart Map<String, String> json, Model model) throws IOException { |
| 377 | + @RequestMapping(value = "/json", method = RequestMethod.POST) |
| 378 | + public String processMultipart(@RequestPart Map<String, String> json, Model model) { |
| 379 | + model.addAttribute("json", json); |
| 380 | + return "redirect:/index"; |
| 381 | + } |
347 | 382 |
|
348 |
| - model.addAttribute("fileContent", part.getInputStream()); |
349 |
| - model.addAttribute("jsonContent", json); |
| 383 | + @RequestMapping(value = "/partattr") |
| 384 | + public String processPartAttribute(PartForm form, |
| 385 | + @RequestPart(required = false) Map<String, String> json, Model model) throws IOException { |
| 386 | + |
| 387 | + if (form != null) { |
| 388 | + Part part = form.getFile(); |
| 389 | + if (0 != part.getSize()) { |
| 390 | + byte[] fileContent = StreamUtils.copyToByteArray(part.getInputStream()); |
| 391 | + model.addAttribute("fileContent", fileContent); |
| 392 | + } |
| 393 | + } |
| 394 | + if (json != null) { |
| 395 | + model.addAttribute("jsonContent", json); |
| 396 | + } |
350 | 397 |
|
351 | 398 | return "redirect:/index";
|
352 | 399 | }
|
353 | 400 |
|
354 |
| - @RequestMapping(value = "/json", method = RequestMethod.POST) |
355 |
| - public String processMultipart(@RequestPart Map<String, String> json, Model model) { |
356 |
| - model.addAttribute("json", json); |
| 401 | + @RequestMapping(value = "/multipartfileattr") |
| 402 | + public String processMultipartFileAttribute(MultipartFileForm form, |
| 403 | + @RequestPart(required = false) Map<String, String> json, Model model) throws IOException { |
| 404 | + |
| 405 | + if (form != null) { |
| 406 | + MultipartFile file = form.getFile(); |
| 407 | + if (!file.isEmpty()) { |
| 408 | + model.addAttribute("fileContent", file.getBytes()); |
| 409 | + } |
| 410 | + } |
| 411 | + if (json != null) { |
| 412 | + model.addAttribute("jsonContent", json); |
| 413 | + } |
| 414 | + |
357 | 415 | return "redirect:/index";
|
358 | 416 | }
|
359 | 417 | }
|
360 | 418 |
|
| 419 | + private static class PartForm { |
| 420 | + |
| 421 | + private Part file; |
| 422 | + |
| 423 | + public PartForm(Part file) { |
| 424 | + this.file = file; |
| 425 | + } |
| 426 | + |
| 427 | + public Part getFile() { |
| 428 | + return file; |
| 429 | + } |
| 430 | + } |
| 431 | + |
| 432 | + private static class MultipartFileForm { |
| 433 | + |
| 434 | + private MultipartFile file; |
| 435 | + |
| 436 | + public MultipartFileForm(MultipartFile file) { |
| 437 | + this.file = file; |
| 438 | + } |
| 439 | + |
| 440 | + public MultipartFile getFile() { |
| 441 | + return file; |
| 442 | + } |
| 443 | + } |
361 | 444 |
|
362 | 445 | private static class RequestWrappingFilter extends OncePerRequestFilter {
|
363 | 446 |
|
364 | 447 | @Override
|
365 | 448 | protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
366 |
| - FilterChain filterChain) throws IOException, ServletException { |
| 449 | + FilterChain filterChain) throws IOException, ServletException { |
367 | 450 |
|
368 | 451 | request = new HttpServletRequestWrapper(request);
|
369 | 452 | filterChain.doFilter(request, response);
|
|
0 commit comments