How to PUT multipart / form-data using Spring MockMvc?

I have a controller method with a PUT method that gets multipart / form-data:

  @RequestMapping(value = "/putIn", method = RequestMethod.PUT) public Foo updateFoo(HttpServletRequest request, @RequestBody Foo foo, @RequestParam("foo_icon") MultipartFile file) { ... } 

and I want to test it using MockMvc . Unfortunately, MockMvcRequestBuilders.fileUpload creates an instance of MockMultipartHttpServletRequestBuilder that has a POST method:

 super(HttpMethod.POST, urlTemplate, urlVariables) 

EDIT: I ca n’t create my own implementation of MockHttpServletRequestBuilder , say

 public MockPutMultipartHttpServletRequestBuilder(String urlTemplate, Object... urlVariables) { super(HttpMethod.PUT, urlTemplate, urlVariables); super.contentType(MediaType.MULTIPART_FORM_DATA); } 

because MockHttpServletRequestBuilder has a package-local constructor.

But I wonder if this is more convenient . Is it possible to do this, maybe I missed some existing class or method for this?

+5
source share
2 answers

Yes, there is a way, and it's easy too!

I ran into the same problem myself. Although I was discouraged by Sam Brannen's answer, it seems that Spring MVC currently supports loading PUT files, since I could just execute such a request using Postman (I use Spring Boot 1.4.2). So, I kept digging and found that the only problem is the fact that the MockMultipartHttpServletRequestBuilder returned by MockMvcRequestBuilders.fileUpload() has a hardcoded method on "POST". Then I discovered the with() method ...

and this allowed me to come up with this neat little trick to force MockMultipartHttpServletRequestBuilder use the "PUT" method:

  MockMultipartFile file = new MockMultipartFile("data", "dummy.csv", "text/plain", "Some dataset...".getBytes()); MockMultipartHttpServletRequestBuilder builder = MockMvcRequestBuilders.fileUpload("/test1/datasets/set1"); builder.with(new RequestPostProcessor() { @Override public MockHttpServletRequest postProcessRequest(MockHttpServletRequest request) { request.setMethod("PUT"); return request; } }); mvc.perform(builder .file(file)) .andExpect(status().ok()); 

It works like a charm!

+19
source

Unfortunately, this is not currently supported in Spring MVC Test, and I don’t see a workflow other than creating my own standard MockPutMultipartHttpServletRequestBuilder code and copy-n-paste from the standard implementation.

For what it's worth, Spring MVC also does not support PUT requests for downloading files by default. Multipart solutions are hardcoded to accept only POST file download requests - for both Apache Commons and standard servlet API support.

If you want Spring to support PUT requests, feel free to open a ticket for Spring with a JIRA tracker issue.

+4
source

All Articles