I'm trying to create a RESTful controller endpoint with Spring MVC 3.2 to upload a file as well as a map of metadata for that file. Defined like this:
@Controller @RequestMapping("/file") public class FileServiceController { @RequestMapping(value="/upload", method=RequestMethod.POST) @ResponseBody public void upload(@RequestParam MultipartFile file, @RequestParam String fileType, @RequestParam(value="metadata") Map<String, List<String>> metadata) { // TODO: stuff with things } }
which I'm then trying to test like this:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = { AppConfig.class }) @WebAppConfiguration public class ProductIngestServiceControllerTest { @Autowired private WebApplicationContext wac; private MockMvc mockMvc; @Mock private FileServiceController controller; @Before public void setup() { mockMvc = MockMvcBuilders.standaloneSetup(controller).build(); } @Test public void testUpload() { MockMultipartFile mockFile = new MockMultipartFile("file", "This is a test file".getBytes()); Map<String, List<String>> metadata = new HashMap<>(); metadata.put("custom0", Arrays.asList("test1", "test2")); metadata.put("custom1", Arrays.asList("test3", "test4", "test5")); metadata.put("custom2", Arrays.asList("test6")); Gson gson = new Gson(); String mapStr = gson.toJson(metadata); mockMvc.perform(fileUpload(baseURL + "/test") .file(mockFile) .param("fileType", "test_type") .param("metadata", mapStr)) .andDo(print()) .andExpect(status().isOk()) .andReturn(); } }
I'm expecting the map to contain just the "customX" entries, but it contains all request parameters instead (except the MultipartFile...).
If I try:
public void upload(@RequestParam MultiValueMap parameters) { ... }
the MultipartFile isn't included in that map either.
Am I going about this the wrong way? The only solution I can come up with at the moment is to just use a String for the metadata RequestParam and do something like:
ObjectMapper mapper = new ObjectMapper(); JsonFactory factory = mapper.getJsonFactory(); JsonParser jp = factory.createJsonParser(testMap); Map<String, List<String>> map = jp.readValueAs(Map.class);
but that feels dirty.
Any help would be greatly appreciated. Thanks!