diff --git a/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java b/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java index 112334157..f9fe96749 100644 --- a/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java +++ b/spring-cloud-function-samples/function-sample-pojo/src/test/java/com/example/SampleApplicationTests.java @@ -92,7 +92,7 @@ public class SampleApplicationTests { } @Test - @Ignore + // @Ignore public void multipart() throws Exception { LinkedMultiValueMap map = new LinkedMultiValueMap<>(); diff --git a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java index cddaac891..34a32a573 100644 --- a/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java +++ b/spring-cloud-function-web/src/main/java/org/springframework/cloud/function/web/flux/FunctionController.java @@ -27,7 +27,11 @@ import org.springframework.cloud.function.web.RequestProcessor.FunctionWrapper; import org.springframework.cloud.function.web.constants.WebRequestConstants; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.http.codec.multipart.FormFieldPart; +import org.springframework.http.codec.multipart.Part; import org.springframework.stereotype.Component; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -49,13 +53,34 @@ public class FunctionController { this.processor = processor; } - @PostMapping(path = "/**", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE, - MediaType.MULTIPART_FORM_DATA_VALUE }) + @PostMapping(path = "/**", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE) @ResponseBody public Mono> form(ServerWebExchange request) { FunctionWrapper wrapper = wrapper(request); return request.getFormData().doOnSuccess(params -> wrapper.params(params)) - .then(processor.post(wrapper, null, false)); + .then(Mono.defer(() -> processor.post(wrapper, null, false))); + } + + @PostMapping(path = "/**", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + @ResponseBody + public Mono> multipart(ServerWebExchange request) { + FunctionWrapper wrapper = wrapper(request); + return request.getMultipartData() + .doOnSuccess(params -> wrapper.params(multi(params))) + .then(Mono.defer(() -> processor.post(wrapper, null, false))); + } + + private MultiValueMap multi(MultiValueMap body) { + MultiValueMap map = new LinkedMultiValueMap<>(); + for (String key : body.keySet()) { + for (Part part : body.get(key)) { + if (part instanceof FormFieldPart) { + FormFieldPart form = (FormFieldPart) part; + map.add(key, form.value()); + } + } + } + return map; } @PostMapping(path = "/**") diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java index 478c7785d..b63bc9a74 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/flux/HttpPostIntegrationTests.java @@ -302,7 +302,6 @@ public class HttpPostIntegrationTests { } @Test - @Ignore public void multipart() throws Exception { LinkedMultiValueMap map = new LinkedMultiValueMap<>(); diff --git a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java index 2f250c4c5..545fb4c19 100644 --- a/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java +++ b/spring-cloud-function-web/src/test/java/org/springframework/cloud/function/web/mvc/HttpPostIntegrationTests.java @@ -307,6 +307,20 @@ public class HttpPostIntegrationTests { String.class).getBody()).isEqualTo("[{\"A\":6,\"B\":11}]"); } + @Test + public void multipart() throws Exception { + + LinkedMultiValueMap map = new LinkedMultiValueMap<>(); + + map.put("A", Arrays.asList("1", "2", "3")); + map.put("B", Arrays.asList("5", "6")); + + assertThat(rest.exchange( + RequestEntity.post(new URI("/sum")).accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.MULTIPART_FORM_DATA).body(map), + String.class).getBody()).isEqualTo("[{\"A\":6,\"B\":11}]"); + } + @Test public void count() throws Exception { List list = Arrays.asList("A", "B", "A");