How to submit multi-part / form data to upload files using SpringMVC and MockMVC

I created a photo downloader that works great with javax.ws.rs. Here is the signature and the main meaning:

@POST @Path("/upload/photo") @Consumes("multipart/form-data") @Produces("application/json") public String uploadPhoto(InputStream stream){ try { int read = 0; FileOutputStream fos = new FileOutputStream(file); CountingOutputStream out = new CountingOutputStream(fos); byte[] bytes = new byte[MAX_UPLOAD_SIZE]; while ((read = stream.read(bytes)) != -1) { out.write(bytes, 0, read); } out.flush(); out.close(); } catch (IOException e) { // TODO throw! e.printStackTrace(); } //... } 

I can verify this using the apache.commons.httpClient library as follows:

  @Test public void testUpload() { int statusCode = 0; String methodResult = null; String endpoint = SERVICE_HOST + "/upload/photo"; PostMethod post = new PostMethod(endpoint); File file = new File("/home/me/Desktop/someFolder/image.jpg"); FileRequestEntity entity = new FileRequestEntity(file, "multipart/form-data"); post.setRequestEntity(entity); try { httpClient.executeMethod(post); methodResult = post.getResponseBodyAsString(); } catch (HttpException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } statusCode = post.getStatusCode(); post.releaseConnection(); //... } 

It works great! The problem is that the rest of the application is written using Spring MVC. When I use the Spring Mock MVC test framework, the program just freezes (shown in the code snippet below this). Here is the SpringMVC code for the bootloader:

 @ResponseBody @RequestMapping( produces="application/json", consumes="multipart/form-data", method=RequestMethod.POST, value="/photo") public String uploadPhoto(@RequestPart("file") MultipartFile multipartFile){ try { int read = 0; FileOutputStream fos = new FileOutputStream(file); CountingOutputStream out = new CountingOutputStream(fos); byte[] bytes = new byte[MAX_UPLOAD_SIZE]; while ((read = multipartFile.getInputStream().read(bytes)) != -1) { out.write(bytes, 0, read); } out.flush(); out.close(); } catch (IOException e) { // TODO throw! e.printStackTrace(); } //... } 

And below is what I used for testing using Spring Mock MVC. I think the problem is with using fileUpload (...). Is there a way to check using a regular post (..) instead, as I can with apache? I would prefer to use InputStream as an argument and not use MultipartFile.

 @Test public void testUpload() throws Exception { String endpoint = BASE_URL + "/upload/photo"; FileInputStream fis = new FileInputStream("/home/me/Desktop/someFolder/image.jpg"); MockMultipartFile multipartFile = new MockMultipartFile("file", fis); mockMvc.perform(fileUpload(endpoint) .file(multipartFile) .contentType(MediaType.MULTIPART_FORM_DATA)) .andExpect(status().isOk()); } 

Ideally, I would like to use Spring MVC and Spring Mock MVC framework, but the code I provided just hangs with the while statement. Is what I'm doing right using the fileUpload method in a Spring test? Any advice is appreciated.

+6
source share
4 answers
  • To add content to the layout, use the content (bytes [])
  • a media type parameter boundary was needed

It was also safe to use the plain old InputStream from java.io as a parameter to the load method and still use the MockMultipartFile in the request.

 @Test public void testUpload() throws Exception { String endpoint = BASE_URL + "/upload/photo"; FileInputStream fis = new FileInputStream("/home/me/Desktop/someDir/image.jpg"); MockMultipartFile multipartFile = new MockMultipartFile("file", fis); HashMap<String, String> contentTypeParams = new HashMap<String, String>(); contentTypeParams.put("boundary", "265001916915724"); MediaType mediaType = new MediaType("multipart", "form-data", contentTypeParams); mockMvc.perform( post(endpoint) .content(multipartFile.getBytes()) .contentType(mediaType)) .andExpect(status().isOk()); } 
+7
source

MockMvcRequestBuilders.fileUpload:

 @Test public void uploadTest() throws Exception { String endpoint = "/service/productsale/5/upload"; FileInputStream fis = new FileInputStream("E:\\test\\test.jpg"); MockMultipartFile multipartFile = new MockMultipartFile("file",fis); mockMvc.perform(MockMvcRequestBuilders.fileUpload(endpoint).file(multipartFile)) .andExpect(MockMvcResultMatchers.model().attributeExists("imageVo")) .andDo(print()) .andExpect(status().isOk()); } 
+3
source

Turning to, the code below may be simpler.

 @Test public void testFileUpload() throws Exception { FileInputStream input = new FileInputStream("/Downloads/WX.png"); MockMultipartFile file = new MockMultipartFile( "image", " WX20180207-134704@2x.png ", "image/png", input); this.mockMvc .perform( multipart("/api/note/image/create") .file(file) .header("Authorization", "BearereyJhbGciOiJIUzUxMiJ9") ); } 
0
source

This link helped me: https://samerabdelkafi.wordpress.com/2014/08/03/spring-mvc-full-java-based-config/

More specifically this configuration: @Override

 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } 
0
source

Source: https://habr.com/ru/post/959355/


All Articles