|
|
|
@ -19,7 +19,9 @@ package org.springframework.test.web.servlet.samples.standalone; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Collections; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
import java.util.Optional; |
|
|
|
import javax.servlet.Filter; |
|
|
|
import javax.servlet.Filter; |
|
|
|
import javax.servlet.FilterChain; |
|
|
|
import javax.servlet.FilterChain; |
|
|
|
import javax.servlet.ServletException; |
|
|
|
import javax.servlet.ServletException; |
|
|
|
@ -28,6 +30,7 @@ import javax.servlet.http.HttpServletRequestWrapper; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import javax.servlet.http.Part; |
|
|
|
import javax.servlet.http.Part; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.Test; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.http.MediaType; |
|
|
|
@ -49,12 +52,12 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @since 5.0 |
|
|
|
* @author Juergen Hoeller |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class MultipartControllerTests { |
|
|
|
public class MultipartControllerTests { |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void multipartRequest() throws Exception { |
|
|
|
public void multipartRequestWithSingleFile() throws Exception { |
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
MockMultipartFile filePart = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
MockMultipartFile filePart = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
|
|
|
|
@ -62,12 +65,127 @@ public class MultipartControllerTests { |
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
.perform(multipart("/test-multipartfile").file(filePart).file(jsonPart)) |
|
|
|
.perform(multipart("/multipartfile").file(filePart).file(jsonPart)) |
|
|
|
.andExpect(status().isFound()) |
|
|
|
.andExpect(status().isFound()) |
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithFileArray() throws Exception { |
|
|
|
|
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile filePart1 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
MockMultipartFile filePart2 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/multipartfilearray").file(filePart1).file(filePart2).file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithFileList() throws Exception { |
|
|
|
|
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile filePart1 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
MockMultipartFile filePart2 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/multipartfilelist").file(filePart1).file(filePart2).file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithOptionalFile() throws Exception { |
|
|
|
|
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile filePart = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/optionalfile").file(filePart).file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithOptionalFileNotPresent() throws Exception { |
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/optionalfile").file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attributeDoesNotExist("fileContent")) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithOptionalFileArray() throws Exception { |
|
|
|
|
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile filePart1 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
MockMultipartFile filePart2 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/optionalfilearray").file(filePart1).file(filePart2).file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithOptionalFileArrayNotPresent() throws Exception { |
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/optionalfilearray").file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attributeDoesNotExist("fileContent")) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithOptionalFileList() throws Exception { |
|
|
|
|
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile filePart1 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
MockMultipartFile filePart2 = new MockMultipartFile("file", "orig", null, fileContent); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/optionalfilelist").file(filePart1).file(filePart2).file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void multipartRequestWithOptionalFileListNotPresent() throws Exception { |
|
|
|
|
|
|
|
byte[] json = "{\"name\":\"yeeeah\"}".getBytes(StandardCharsets.UTF_8); |
|
|
|
|
|
|
|
MockMultipartFile jsonPart = new MockMultipartFile("json", "json", "application/json", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
|
|
|
|
.perform(multipart("/optionalfilelist").file(jsonPart)) |
|
|
|
|
|
|
|
.andExpect(status().isFound()) |
|
|
|
|
|
|
|
.andExpect(model().attributeDoesNotExist("fileContent")) |
|
|
|
|
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void multipartRequestWithServletParts() throws Exception { |
|
|
|
public void multipartRequestWithServletParts() throws Exception { |
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
byte[] fileContent = "bar".getBytes(StandardCharsets.UTF_8); |
|
|
|
@ -78,7 +196,7 @@ public class MultipartControllerTests { |
|
|
|
jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON); |
|
|
|
jsonPart.getHeaders().setContentType(MediaType.APPLICATION_JSON); |
|
|
|
|
|
|
|
|
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
standaloneSetup(new MultipartController()).build() |
|
|
|
.perform(multipart("/test-multipartfile").part(filePart).part(jsonPart)) |
|
|
|
.perform(multipart("/multipartfile").part(filePart).part(jsonPart)) |
|
|
|
.andExpect(status().isFound()) |
|
|
|
.andExpect(status().isFound()) |
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
.andExpect(model().attribute("fileContent", fileContent)) |
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
.andExpect(model().attribute("jsonContent", Collections.singletonMap("name", "yeeeah"))); |
|
|
|
@ -93,34 +211,98 @@ public class MultipartControllerTests { |
|
|
|
MockMvc mockMvc = standaloneSetup(new MultipartController()).addFilter(filter).build(); |
|
|
|
MockMvc mockMvc = standaloneSetup(new MultipartController()).addFilter(filter).build(); |
|
|
|
|
|
|
|
|
|
|
|
Map<String, String> jsonMap = Collections.singletonMap("name", "yeeeah"); |
|
|
|
Map<String, String> jsonMap = Collections.singletonMap("name", "yeeeah"); |
|
|
|
mockMvc.perform(multipart("/test-json").file(jsonPart)).andExpect(model().attribute("json", jsonMap)); |
|
|
|
mockMvc.perform(multipart("/json").file(jsonPart)).andExpect(model().attribute("json", jsonMap)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Controller |
|
|
|
@Controller |
|
|
|
private static class MultipartController { |
|
|
|
private static class MultipartController { |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/test-multipartfile", method = RequestMethod.POST) |
|
|
|
@RequestMapping(value = "/multipartfile", method = RequestMethod.POST) |
|
|
|
public String processMultipartFile(@RequestParam MultipartFile file, |
|
|
|
public String processMultipartFile(@RequestParam MultipartFile file, |
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
model.addAttribute("fileContent", file.getBytes()); |
|
|
|
model.addAttribute("fileContent", file.getBytes()); |
|
|
|
|
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
|
|
|
|
return "redirect:/index"; |
|
|
|
return "redirect:/index"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/test-part", method = RequestMethod.POST) |
|
|
|
@RequestMapping(value = "/multipartfilearray", method = RequestMethod.POST) |
|
|
|
public String processPart(@RequestParam Part part, |
|
|
|
public String processMultipartFileArray(@RequestParam MultipartFile[] file, |
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] content = file[0].getBytes(); |
|
|
|
|
|
|
|
Assert.assertArrayEquals(content, file[1].getBytes()); |
|
|
|
|
|
|
|
model.addAttribute("fileContent", content); |
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return "redirect:/index"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/multipartfilelist", method = RequestMethod.POST) |
|
|
|
|
|
|
|
public String processMultipartFileList(@RequestParam List<MultipartFile> file, |
|
|
|
|
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
byte[] content = file.get(0).getBytes(); |
|
|
|
|
|
|
|
Assert.assertArrayEquals(content, file.get(1).getBytes()); |
|
|
|
|
|
|
|
model.addAttribute("fileContent", content); |
|
|
|
|
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return "redirect:/index"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/optionalfile", method = RequestMethod.POST) |
|
|
|
|
|
|
|
public String processOptionalFile(@RequestParam Optional<MultipartFile> file, |
|
|
|
|
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (file.isPresent()) { |
|
|
|
|
|
|
|
model.addAttribute("fileContent", file.get().getBytes()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return "redirect:/index"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/optionalfilearray", method = RequestMethod.POST) |
|
|
|
|
|
|
|
public String processOptionalFileArray(@RequestParam Optional<MultipartFile[]> file, |
|
|
|
|
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (file.isPresent()) { |
|
|
|
|
|
|
|
byte[] content = file.get()[0].getBytes(); |
|
|
|
|
|
|
|
Assert.assertArrayEquals(content, file.get()[1].getBytes()); |
|
|
|
|
|
|
|
model.addAttribute("fileContent", content); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return "redirect:/index"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/optionalfilelist", method = RequestMethod.POST) |
|
|
|
|
|
|
|
public String processOptionalFileList(@RequestParam Optional<List<MultipartFile>> file, |
|
|
|
|
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (file.isPresent()) { |
|
|
|
|
|
|
|
byte[] content = file.get().get(0).getBytes(); |
|
|
|
|
|
|
|
Assert.assertArrayEquals(content, file.get().get(1).getBytes()); |
|
|
|
|
|
|
|
model.addAttribute("fileContent", content); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return "redirect:/index"; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/part", method = RequestMethod.POST) |
|
|
|
|
|
|
|
public String processPart(@RequestParam Part part, |
|
|
|
|
|
|
|
@RequestPart Map<String, String> json, Model model) throws IOException { |
|
|
|
|
|
|
|
|
|
|
|
model.addAttribute("fileContent", part.getInputStream()); |
|
|
|
model.addAttribute("fileContent", part.getInputStream()); |
|
|
|
|
|
|
|
model.addAttribute("jsonContent", json); |
|
|
|
|
|
|
|
|
|
|
|
return "redirect:/index"; |
|
|
|
return "redirect:/index"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@RequestMapping(value = "/test-json", method = RequestMethod.POST) |
|
|
|
@RequestMapping(value = "/json", method = RequestMethod.POST) |
|
|
|
public String processMultipart(@RequestPart Map<String, String> json, Model model) { |
|
|
|
public String processMultipart(@RequestPart Map<String, String> json, Model model) { |
|
|
|
model.addAttribute("json", json); |
|
|
|
model.addAttribute("json", json); |
|
|
|
return "redirect:/index"; |
|
|
|
return "redirect:/index"; |
|
|
|
@ -139,4 +321,4 @@ public class MultipartControllerTests { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|