Skip to content

Commit

Permalink
Added FormData object (#38)
Browse files Browse the repository at this point in the history
* Added FormData object

* Fixed PMD checks

* Updated README with FormData example

* Added FormData creation example
  • Loading branch information
GuiSim authored and xxlabaza committed Mar 28, 2018
1 parent fcfe0a5 commit 9c545e3
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 5 deletions.
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
8 changes: 8 additions & 0 deletions feign-form/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ limitations under the License.
<maven.compiler.target>1.6</maven.compiler.target>
</properties>

<dependencies>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
Expand Down
43 changes: 43 additions & 0 deletions feign-form/src/main/java/feign/form/FormData.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -57,6 +58,7 @@ public class MultipartFormContentProcessor implements ContentProcessor {
public MultipartFormContentProcessor (Encoder delegate) {
writers = new ArrayList<Writer>(6);
addWriter(new ByteArrayWriter());
addWriter(new FormDataWriter());
addWriter(new SingleFileWriter());
addWriter(new ManyFilesWriter());
addWriter(new ParameterWriter());
Expand Down
35 changes: 35 additions & 0 deletions feign-form/src/main/java/feign/form/multipart/FormDataWriter.java
Original file line number Diff line number Diff line change
@@ -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());
}
}
8 changes: 8 additions & 0 deletions feign-form/src/test/java/feign/form/BasicClientTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
11 changes: 11 additions & 0 deletions feign-form/src/test/java/feign/form/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,15 @@ public ResponseEntity<String> 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<String> uploadFormData (@RequestPart("file") MultipartFile file) {
val status = file != null
? OK
: I_AM_A_TEAPOT;
return ResponseEntity.status(status).body(file.getContentType());
}
}
11 changes: 8 additions & 3 deletions feign-form/src/test/java/feign/form/TestClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
*
Expand Down Expand Up @@ -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);
}

0 comments on commit 9c545e3

Please sign in to comment.