You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2020/08/05 00:52:39 UTC
[servicecomb-java-chassis] 01/02: [SCB-2058] fix SpringMVC provider
not support non-file-type RequestPart problem
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
commit 09746aac548b73a8b472183625a591c586b3c52e
Author: yhs0092 <yh...@163.com>
AuthorDate: Mon Aug 3 19:13:18 2020 +0800
[SCB-2058] fix SpringMVC provider not support non-file-type RequestPart problem
- add MultipartFilePropertyCreator to enable ModelConverters resolving MultipartFile param
- make RequestPartAnnotationProcessor recognize non-file-type RequestPart param
---
.../apache/servicecomb/it/testcase/TestUpload.java | 82 ++++++++++
.../servicecomb/it/schema/UploadJaxrsSchema.java | 30 ++++
.../it/schema/UploadSpringmvcSchema.java | 15 ++
.../annotation/RequestPartAnnotationProcessor.java | 34 ++++-
.../creator/MultipartFilePropertyCreator.java | 38 +++++
...swagger.extend.property.creator.PropertyCreator | 18 +++
.../RequestPartAnnotationProcessorTest.java | 169 +++++++++++++++++++++
.../creator/MultipartFilePropertyCreatorTest.java | 42 +++++
8 files changed, 423 insertions(+), 5 deletions(-)
diff --git a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestUpload.java b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestUpload.java
index 8aede2f..57a7a88 100644
--- a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestUpload.java
+++ b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/testcase/TestUpload.java
@@ -20,19 +20,25 @@ import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.servicecomb.it.Consumers;
+import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
+import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
public class TestUpload {
@@ -47,6 +53,10 @@ public class TestUpload {
private static final String message = "cseMessage";
interface UploadIntf {
+ Map<String, String> uploadMultiformMix(Resource file,
+ List<Resource> fileList,
+ String str,
+ List<String> strList);
}
private static Consumers<UploadIntf> consumersSpringmvc = new Consumers<>("uploadSpringmvcSchema",
@@ -316,6 +326,78 @@ public class TestUpload {
Assert.assertTrue(containsAll(result, "hello1", "cse4", "cse3", "中文 2", message));
}
+ @Test
+ public void testUploadMultiformMix_RestTemplate_SpringMVC() {
+ Map<String, Object> map = new HashMap<>();
+ List<Resource> fileList = new ArrayList<>();
+ fileList.add(fileSystemResource2);
+ map.put("file", fileSystemResource1);
+ map.put("fileList", fileList);
+ map.put("str", message);
+ map.put("strList", Collections.singletonList("2.中文测试"));
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+ ResponseEntity<Map<String, String>> response =
+ consumersSpringmvc.getSCBRestTemplate().exchange("/uploadMultiformMix", HttpMethod.POST,
+ new HttpEntity<>(map, headers), new ParameterizedTypeReference<Map<String, String>>() {
+ });
+ Map<String, String> responseBody = response.getBody();
+ Assert.assertThat(responseBody, Matchers.notNullValue());
+ Assert.assertThat(responseBody.get("file"), Matchers.is("hello1"));
+ Assert.assertThat(responseBody.get("fileList"), Matchers.is("中文 2"));
+ Assert.assertThat(responseBody.get("str"), Matchers.is("cseMessage"));
+ Assert.assertThat(responseBody.get("strList"), Matchers.is("[2.中文测试]"));
+ }
+
+ @Test
+ public void testUploadMultiformMix_Rpc_SpringMVC() {
+ List<Resource> fileList = new ArrayList<>();
+ fileList.add(fileSystemResource2);
+ Map<String, String> responseBody =
+ consumersSpringmvc.getIntf().uploadMultiformMix(
+ fileSystemResource1, fileList, message, Collections.singletonList("2.中文测试"));
+ Assert.assertThat(responseBody.get("file"), Matchers.is("hello1"));
+ Assert.assertThat(responseBody.get("fileList"), Matchers.is("中文 2"));
+ Assert.assertThat(responseBody.get("str"), Matchers.is("cseMessage"));
+ Assert.assertThat(responseBody.get("strList"), Matchers.is("[2.中文测试]"));
+ }
+
+ @Test
+ public void testUploadMultiformMix_RestTemplate_JAXRS() {
+ Map<String, Object> map = new HashMap<>();
+ List<FileSystemResource> fileList = new ArrayList<>();
+ fileList.add(fileSystemResource2);
+ map.put("file", fileSystemResource1);
+ map.put("fileList", fileList);
+ map.put("str", message);
+ map.put("strList", Collections.singletonList("2.中文测试"));
+ HttpHeaders headers = new HttpHeaders();
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
+ ResponseEntity<Map<String, String>> response =
+ consumersJaxrs.getSCBRestTemplate().exchange("/uploadMultiformMix", HttpMethod.POST,
+ new HttpEntity<>(map, headers), new ParameterizedTypeReference<Map<String, String>>() {
+ });
+ Map<String, String> responseBody = response.getBody();
+ Assert.assertThat(responseBody, Matchers.notNullValue());
+ Assert.assertThat(responseBody.get("file"), Matchers.is("hello1"));
+ Assert.assertThat(responseBody.get("fileList"), Matchers.is("中文 2"));
+ Assert.assertThat(responseBody.get("str"), Matchers.is("cseMessage"));
+ Assert.assertThat(responseBody.get("strList"), Matchers.is("[2.中文测试]"));
+ }
+
+ @Test
+ public void testUploadMultiformMix_Rpc_JAXRS() {
+ List<Resource> fileList = new ArrayList<>();
+ fileList.add(fileSystemResource2);
+ Map<String, String> responseBody =
+ consumersJaxrs.getIntf().uploadMultiformMix(
+ fileSystemResource1, fileList, message, Collections.singletonList("2.中文测试"));
+ Assert.assertThat(responseBody.get("file"), Matchers.is("hello1"));
+ Assert.assertThat(responseBody.get("fileList"), Matchers.is("中文 2"));
+ Assert.assertThat(responseBody.get("str"), Matchers.is("cseMessage"));
+ Assert.assertThat(responseBody.get("strList"), Matchers.is("[2.中文测试]"));
+ }
+
private static boolean containsAll(String str, String... strings) {
for (String string : strings) {
if (!str.contains(string)) {
diff --git a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadJaxrsSchema.java b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadJaxrsSchema.java
index 0f343e2..ad41f38 100644
--- a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadJaxrsSchema.java
+++ b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadJaxrsSchema.java
@@ -18,8 +18,11 @@ package org.apache.servicecomb.it.schema;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import javax.servlet.http.Part;
import javax.ws.rs.FormParam;
@@ -30,6 +33,7 @@ import javax.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.web.multipart.MultipartFile;
@RestSchema(schemaId = "uploadJaxrsSchema")
@Path("/v1/uploadJaxrsSchema")
@@ -138,4 +142,30 @@ public class UploadJaxrsSchema {
}
return "";
}
+
+ @Path("/uploadMultiformMix")
+ @POST
+ public Map<String, String> uploadMultiformMix(@FormParam("file") MultipartFile file,
+ @FormParam("fileList") List<MultipartFile> fileList,
+ @FormParam("str") String str,
+ @FormParam("strList") List<String> strList) throws IOException {
+ HashMap<String, String> map = new HashMap<>();
+ map.put("file", new String(file.getBytes(), StandardCharsets.UTF_8.name()));
+ map.put("fileList", _fileUpload(fileList));
+ map.put("str", str);
+ map.put("strList", strList.toString());
+ return map;
+ }
+
+ private static String _fileUpload(List<MultipartFile> fileList) {
+ StringBuilder stringBuilder = new StringBuilder();
+ try {
+ for (MultipartFile multipartFile : fileList) {
+ stringBuilder.append(IOUtils.toString(multipartFile.getBytes(), StandardCharsets.UTF_8.name()));
+ }
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ return stringBuilder.toString();
+ }
}
diff --git a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadSpringmvcSchema.java b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadSpringmvcSchema.java
index 90d24f4..ff29bfc 100644
--- a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadSpringmvcSchema.java
+++ b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/UploadSpringmvcSchema.java
@@ -20,7 +20,9 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.servicecomb.provider.rest.common.RestSchema;
@@ -96,6 +98,19 @@ public class UploadSpringmvcSchema {
return _fileUpload(file1) + name;
}
+ @RequestMapping(path = "/uploadMultiformMix", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+ public Map<String, String> uploadMultiformMix(@RequestPart(name = "file") MultipartFile file,
+ @RequestPart(name = "fileList") List<MultipartFile> fileList,
+ @RequestPart("str") String str,
+ @RequestPart("strList") List<String> strList) throws IOException {
+ HashMap<String, String> map = new HashMap<>();
+ map.put("file", new String(file.getBytes(), StandardCharsets.UTF_8.name()));
+ map.put("fileList", _fileUpload(fileList));
+ map.put("str", str);
+ map.put("strList", strList.toString());
+ return map;
+ }
+
private static String _fileUpload(List<MultipartFile> fileList) {
StringBuilder stringBuilder = new StringBuilder();
try {
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessor.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessor.java
index 4b381ec..3041527 100644
--- a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessor.java
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessor.java
@@ -23,13 +23,14 @@ import org.apache.servicecomb.swagger.generator.ParameterProcessor;
import org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;
import org.springframework.web.bind.annotation.RequestPart;
+import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
+import io.swagger.converter.ModelConverters;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.models.parameters.FormParameter;
import io.swagger.models.properties.ArrayProperty;
-import io.swagger.models.properties.FileProperty;
import io.swagger.models.properties.Property;
public class RequestPartAnnotationProcessor implements
@@ -56,11 +57,34 @@ public class RequestPartAnnotationProcessor implements
@Override
public void fillParameter(Swagger swagger, Operation operation, FormParameter formParameter, Type type,
RequestPart requestPart) {
- Property property = new FileProperty();
- if (TypeFactory.defaultInstance().constructType(type).isContainerType()) {
- property = new ArrayProperty(new FileProperty());
- }
+ Property property = resolveParamProperty(type);
+
formParameter.setProperty(property);
formParameter.setRequired(requestPart.required());
}
+
+ private Property resolveParamProperty(Type type) {
+ JavaType javaType = TypeFactory.defaultInstance().constructType(type);
+ if (javaType.isContainerType()) {
+ return resolvePropertyAsContainerType(javaType);
+ }
+ return ModelConverters.getInstance().readAsProperty(type);
+ }
+
+ private Property resolvePropertyAsContainerType(JavaType javaType) {
+ // At present, only array and collection of Part params are supported,
+ // but Map type is also a kind of container type.
+ // Although Map is not supported now, we still consider to take the type of value to generate a property.
+ // Therefore, here we use lastContainedTypeIndex to get the contained type.
+ int lastContainedTypeIndex = javaType.containedTypeCount() - 1;
+ JavaType containedItemType;
+ if (lastContainedTypeIndex < 0) {
+ // javaType may be an array
+ containedItemType = javaType.getContentType();
+ } else {
+ containedItemType = javaType.containedType(lastContainedTypeIndex);
+ }
+ Property containedItemProperty = ModelConverters.getInstance().readAsProperty(containedItemType);
+ return new ArrayProperty(containedItemProperty);
+ }
}
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreator.java b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreator.java
new file mode 100644
index 0000000..8e9f217
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/main/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreator.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.swagger.generator.springmvc.property.creator;
+
+import org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator;
+import org.springframework.web.multipart.MultipartFile;
+
+import io.swagger.models.properties.FileProperty;
+import io.swagger.models.properties.Property;
+
+public class MultipartFilePropertyCreator implements PropertyCreator {
+ private final Class<?>[] classes = {MultipartFile.class};
+
+ @Override
+ public Property createProperty() {
+ return new FileProperty();
+ }
+
+ @Override
+ public Class<?>[] classes() {
+ return classes;
+ }
+}
diff --git a/swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator b/swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator
new file mode 100644
index 0000000..97564b8
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.swagger.generator.springmvc.property.creator.MultipartFilePropertyCreator
\ No newline at end of file
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessorTest.java b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessorTest.java
new file mode 100644
index 0000000..95a1b40
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/processor/annotation/RequestPartAnnotationProcessorTest.java
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.swagger.generator.springmvc.processor.annotation;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.List;
+
+import org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+import io.swagger.models.parameters.FormParameter;
+import io.swagger.models.properties.FileProperty;
+import io.swagger.models.properties.StringProperty;
+
+public class RequestPartAnnotationProcessorTest {
+ private static Method producerMethod;
+
+ private static RequestPartAnnotationProcessor requestPartAnnotationProcessor = new RequestPartAnnotationProcessor();
+
+ @BeforeClass
+ public static void beforeClass() {
+ for (Method method : DemoRest.class.getDeclaredMethods()) {
+ if (method.getName().equals("fun")) {
+ producerMethod = method;
+ break;
+ }
+ }
+ }
+
+ @Test
+ public void getProcessType() {
+ Assert.assertEquals(requestPartAnnotationProcessor.getProcessType(),
+ RequestPart.class);
+ }
+
+ @Test
+ public void getParameterName_fromValue() {
+ Parameter[] parameters = producerMethod.getParameters();
+
+ Parameter stringParam = parameters[0];
+ RequestPart stringParamAnnotation = stringParam.getAnnotation(RequestPart.class);
+ Assert.assertThat(requestPartAnnotationProcessor.getParameterName(stringParamAnnotation),
+ Matchers.is("stringParam"));
+ }
+
+ @Test
+ public void getParameterName_fromName() {
+ Parameter[] parameters = producerMethod.getParameters();
+
+ Parameter intParam = parameters[1];
+ RequestPart intParamAnnotation = intParam.getAnnotation(RequestPart.class);
+ Assert.assertThat(requestPartAnnotationProcessor.getParameterName(intParamAnnotation),
+ Matchers.is("intParam"));
+ }
+
+ @Test
+ public void getHttpParameterType() {
+ Assert.assertThat(requestPartAnnotationProcessor.getHttpParameterType(null),
+ Matchers.is(HttpParameterType.FORM));
+ }
+
+ @Test
+ public void fillParameter_simpleType() {
+ Parameter param = producerMethod.getParameters()[0];
+ RequestPart requestPartAnnotation = param.getAnnotation(RequestPart.class);
+ FormParameter formParameter = new FormParameter();
+ requestPartAnnotationProcessor
+ .fillParameter(null, null, formParameter, param.getParameterizedType(), requestPartAnnotation);
+
+ Assert.assertThat(formParameter.getIn(), Matchers.is("formData"));
+ Assert.assertThat(formParameter.getType(), Matchers.is("string"));
+ }
+
+ @Test
+ public void fillParameter_simpleType_arrayPart() {
+ Parameter param = producerMethod.getParameters()[2];
+ RequestPart requestPartAnnotation = param.getAnnotation(RequestPart.class);
+ FormParameter formParameter = new FormParameter();
+ requestPartAnnotationProcessor
+ .fillParameter(null, null, formParameter, param.getParameterizedType(), requestPartAnnotation);
+
+ Assert.assertThat(formParameter.getIn(), Matchers.is("formData"));
+ Assert.assertThat(formParameter.getType(), Matchers.is("array"));
+ Assert.assertThat(formParameter.getItems(), Matchers.instanceOf(StringProperty.class));
+ }
+
+ @Test
+ public void fillParameter_simpleType_collectionPart() {
+ Parameter param = producerMethod.getParameters()[3];
+ RequestPart requestPartAnnotation = param.getAnnotation(RequestPart.class);
+ FormParameter formParameter = new FormParameter();
+ requestPartAnnotationProcessor
+ .fillParameter(null, null, formParameter, param.getParameterizedType(), requestPartAnnotation);
+
+ Assert.assertThat(formParameter.getIn(), Matchers.is("formData"));
+ Assert.assertThat(formParameter.getType(), Matchers.is("array"));
+ Assert.assertThat(formParameter.getItems(), Matchers.instanceOf(StringProperty.class));
+ }
+
+ @Test
+ public void fillParameter_uploadFile() {
+ Parameter param = producerMethod.getParameters()[4];
+ RequestPart requestPartAnnotation = param.getAnnotation(RequestPart.class);
+ FormParameter formParameter = new FormParameter();
+ requestPartAnnotationProcessor
+ .fillParameter(null, null, formParameter, param.getParameterizedType(), requestPartAnnotation);
+
+ Assert.assertThat(formParameter.getIn(), Matchers.is("formData"));
+ Assert.assertThat(formParameter.getType(), Matchers.is("file"));
+ }
+
+ @Test
+ public void fillParameter_uploadFile_arrayPart() {
+ Parameter param = producerMethod.getParameters()[5];
+ RequestPart requestPartAnnotation = param.getAnnotation(RequestPart.class);
+ FormParameter formParameter = new FormParameter();
+ requestPartAnnotationProcessor
+ .fillParameter(null, null, formParameter, param.getParameterizedType(), requestPartAnnotation);
+
+ Assert.assertThat(formParameter.getIn(), Matchers.is("formData"));
+ Assert.assertThat(formParameter.getType(), Matchers.is("array"));
+ Assert.assertThat(formParameter.getItems(), Matchers.instanceOf(FileProperty.class));
+ }
+
+ @Test
+ public void fillParameter_uploadFile_collectionPart() {
+ Parameter param = producerMethod.getParameters()[6];
+ RequestPart requestPartAnnotation = param.getAnnotation(RequestPart.class);
+ FormParameter formParameter = new FormParameter();
+ requestPartAnnotationProcessor
+ .fillParameter(null, null, formParameter, param.getParameterizedType(), requestPartAnnotation);
+
+ Assert.assertThat(formParameter.getIn(), Matchers.is("formData"));
+ Assert.assertThat(formParameter.getType(), Matchers.is("array"));
+ Assert.assertThat(formParameter.getItems(), Matchers.instanceOf(FileProperty.class));
+ }
+
+ public static class DemoRest {
+ public void fun(@RequestPart("stringParam") String stringParam,
+ @RequestPart(name = "intParam") int intParam,
+ @RequestPart("stringParamArray") String[] stringParamArray,
+ @RequestPart("stringParamCollection") List<String> stringParamCollection,
+ @RequestPart("file") MultipartFile file,
+ @RequestPart("fileArray") MultipartFile[] fileArray,
+ @RequestPart("fileCollection") List<MultipartFile> fileCollection) {
+ }
+ }
+}
\ No newline at end of file
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreatorTest.java b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreatorTest.java
new file mode 100644
index 0000000..619e777
--- /dev/null
+++ b/swagger/swagger-generator/generator-springmvc/src/test/java/org/apache/servicecomb/swagger/generator/springmvc/property/creator/MultipartFilePropertyCreatorTest.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.swagger.generator.springmvc.property.creator;
+
+import org.hamcrest.Matchers;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.web.multipart.MultipartFile;
+
+import io.swagger.models.properties.FileProperty;
+import io.swagger.models.properties.Property;
+
+public class MultipartFilePropertyCreatorTest {
+ private MultipartFilePropertyCreator multipartFilePropertyCreator = new MultipartFilePropertyCreator();
+
+ @Test
+ public void createProperty() {
+ Property property = multipartFilePropertyCreator.createProperty();
+ Assert.assertThat(property, Matchers.instanceOf(FileProperty.class));
+ }
+
+ @Test
+ public void classes() {
+ Class<?>[] classes = multipartFilePropertyCreator.classes();
+ Assert.assertThat(classes, Matchers.arrayContaining(MultipartFile.class));
+ }
+}