diff --git a/README.md b/README.md
index fc86e8e..3592232 100644
--- a/README.md
+++ b/README.md
@@ -80,18 +80,37 @@ interface SomeApi {
...
+ // File parameter
@RequestLine("POST /send_photo")
@Headers("Content-Type: multipart/form-data")
void sendPhoto (@Param("is_public") Boolean isPublic, @Param("photo") File photo);
+ // byte[] parameter
+ @RequestLine("POST /send_photo")
+ @Headers("Content-Type: multipart/form-data")
+ void sendPhoto (@Param("is_public") Boolean isPublic, @Param("photo") byte[] photo);
+
+ // FormData parameter
+ @RequestLine("POST /send_photo")
+ @Headers("Content-Type: multipart/form-data")
+ void sendPhoto (@Param("is_public") Boolean isPublic, @Param("photo") FormData photo);
...
}
```
-In example above, we send file in parameter named **photo** with additional field in form **is_public**.
+In the example above, the `sendPhoto` method uses the `photo` parameter using three different supported types.
-> **IMPORTANT:** You can specify your files in API method by declaring type **File** or **byte[]**.
+* `File` will use the File's extension to detect the `Content-Type`.
+* `byte[]` will use `application/octet-stream` as `Content-Type`.
+* `FormData` will use the `FormData`'s `Content-Type`.
+
+`FormData` is custom object that wraps a `byte[]` and defines a `Content-Type` like this:
+
+```java
+ FormData formData = new FormData("image/png", myDataAsByteArray);
+ someApi.sendPhoto(true, formData);
+```
### Spring MultipartFile and Spring Cloud Netflix @FeignClient support
diff --git a/feign-form/pom.xml b/feign-form/pom.xml
index 9cebe27..f749067 100644
--- a/feign-form/pom.xml
+++ b/feign-form/pom.xml
@@ -37,6 +37,14 @@ limitations under the License.
1.6
+
+
+ com.google.code.findbugs
+ annotations
+ 3.0.1
+
+
+
diff --git a/feign-form/src/main/java/feign/form/FormData.java b/feign-form/src/main/java/feign/form/FormData.java
new file mode 100644
index 0000000..e30a83b
--- /dev/null
+++ b/feign-form/src/main/java/feign/form/FormData.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2018 Artem Labazin
+ *
+ * Licensed 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 feign.form;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * This object encapsulates a byte array and its associated content type.
+ * Use if if you want to specify the content type of your provided byte array.
+ */
+
+@SuppressFBWarnings({"EI_EXPOSE_REP", "EI_EXPOSE_REP2"})
+public final class FormData {
+ private final String contentType;
+ private final byte[] data;
+
+ public FormData (String contentType, byte[] data) {
+ this.contentType = contentType;
+ this.data = data;
+ }
+
+ public String getContentType () {
+ return contentType;
+ }
+
+ public byte[] getData () {
+ return data;
+ }
+}
diff --git a/feign-form/src/main/java/feign/form/MultipartFormContentProcessor.java b/feign-form/src/main/java/feign/form/MultipartFormContentProcessor.java
index e44207b..7cadd5f 100644
--- a/feign-form/src/main/java/feign/form/MultipartFormContentProcessor.java
+++ b/feign-form/src/main/java/feign/form/MultipartFormContentProcessor.java
@@ -29,6 +29,7 @@
import feign.codec.Encoder;
import feign.form.multipart.ByteArrayWriter;
import feign.form.multipart.DelegateWriter;
+import feign.form.multipart.FormDataWriter;
import feign.form.multipart.ManyFilesWriter;
import feign.form.multipart.Output;
import feign.form.multipart.ParameterWriter;
@@ -57,6 +58,7 @@ public class MultipartFormContentProcessor implements ContentProcessor {
public MultipartFormContentProcessor (Encoder delegate) {
writers = new ArrayList(6);
addWriter(new ByteArrayWriter());
+ addWriter(new FormDataWriter());
addWriter(new SingleFileWriter());
addWriter(new ManyFilesWriter());
addWriter(new ParameterWriter());
diff --git a/feign-form/src/main/java/feign/form/multipart/FormDataWriter.java b/feign-form/src/main/java/feign/form/multipart/FormDataWriter.java
new file mode 100644
index 0000000..07e70c7
--- /dev/null
+++ b/feign-form/src/main/java/feign/form/multipart/FormDataWriter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 Artem Labazin
+ *
+ * Licensed 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 feign.form.multipart;
+
+import feign.form.FormData;
+
+import lombok.val;
+
+public class FormDataWriter extends AbstractWriter {
+ @Override
+ public boolean isApplicable (Object value) {
+ return value instanceof FormData;
+ }
+
+ @Override
+ protected void write (Output output, String key, Object value) throws Exception {
+ val formData = (FormData) value;
+ writeFileMetadata(output, key, null, formData.getContentType());
+ output.write(formData.getData());
+ }
+}
diff --git a/feign-form/src/test/java/feign/form/BasicClientTest.java b/feign-form/src/test/java/feign/form/BasicClientTest.java
index d78c1b1..4085f5a 100644
--- a/feign-form/src/test/java/feign/form/BasicClientTest.java
+++ b/feign-form/src/test/java/feign/form/BasicClientTest.java
@@ -28,6 +28,7 @@
import java.nio.file.Paths;
import java.util.Map;
import lombok.val;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -158,4 +159,11 @@ public void testUnknownTypeFile() throws Exception {
val stringResponse = api.uploadUnknownType(path.toFile());
Assert.assertEquals("application/octet-stream", stringResponse);
}
+
+ @Test
+ public void testFormData() throws Exception {
+ val formData = new FormData("application/custom-type", "Allo".getBytes("UTF-8"));
+ val stringResponse = api.uploadFormData(formData);
+ Assert.assertEquals("application/custom-type", stringResponse);
+ }
}
diff --git a/feign-form/src/test/java/feign/form/Server.java b/feign-form/src/test/java/feign/form/Server.java
index ad924aa..fe57c1e 100644
--- a/feign-form/src/test/java/feign/form/Server.java
+++ b/feign-form/src/test/java/feign/form/Server.java
@@ -178,4 +178,15 @@ public ResponseEntity uploadUnknownType (@RequestPart("file") MultipartF
: I_AM_A_TEAPOT;
return ResponseEntity.status(status).body(file.getContentType());
}
+
+ @PostMapping(
+ path = "/upload/form_data",
+ consumes = MULTIPART_FORM_DATA_VALUE
+ )
+ public ResponseEntity uploadFormData (@RequestPart("file") MultipartFile file) {
+ val status = file != null
+ ? OK
+ : I_AM_A_TEAPOT;
+ return ResponseEntity.status(status).body(file.getContentType());
+ }
}
diff --git a/feign-form/src/test/java/feign/form/TestClient.java b/feign-form/src/test/java/feign/form/TestClient.java
index d12b73d..ed4b017 100644
--- a/feign-form/src/test/java/feign/form/TestClient.java
+++ b/feign-form/src/test/java/feign/form/TestClient.java
@@ -16,14 +16,15 @@
package feign.form;
+import java.io.File;
+import java.util.List;
+import java.util.Map;
+
import feign.Headers;
import feign.Param;
import feign.QueryMap;
import feign.RequestLine;
import feign.Response;
-import java.io.File;
-import java.util.List;
-import java.util.Map;
/**
*
@@ -69,4 +70,8 @@ public interface TestClient {
@RequestLine("POST /upload/unknown_type")
@Headers("Content-Type: multipart/form-data")
String uploadUnknownType (@Param("file") File file);
+
+ @RequestLine("POST /upload/form_data")
+ @Headers("Content-Type: multipart/form-data")
+ String uploadFormData (@Param("file") FormData formData);
}