Skip to content

Commit

Permalink
Support programmatic multipart/form-data responses
Browse files Browse the repository at this point in the history
With these changes, users can also manually append the parts of the form using the class `MultipartFormDataOutput` as:

```java
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.jboss.resteasy.reactive.server.core.multipart.MultipartFormDataOutput;

@path("multipart")
public class Endpoint {

    @get
    @produces(MediaType.MULTIPART_FORM_DATA)
    @path("file")
    public MultipartFormDataOutput getFile() {
        MultipartFormDataOutput form = new MultipartFormDataOutput();
        form.addFormData("person", new Person("John"), MediaType.APPLICATION_JSON_TYPE);
        form.addFormData("status", "a status", MediaType.TEXT_PLAIN_TYPE)
                .getHeaders().putSingle("extra-header", "extra-value");
        return form;
    }
}
```

Fix quarkusio#28631

This last approach allows you adding extra headers to the output part.

(cherry picked from commit 6967fbc)
  • Loading branch information
Sgitario authored and zakkak committed Nov 15, 2022
1 parent acd8eed commit 48e52af
Show file tree
Hide file tree
Showing 14 changed files with 221 additions and 339 deletions.
29 changes: 29 additions & 0 deletions docs/src/main/asciidoc/resteasy-reactive.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,35 @@ public class Endpoint {
}
----

Additionally, you can also manually append the parts of the form using the class `MultipartFormDataOutput` as:

[source,java]
----
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.jboss.resteasy.reactive.server.core.multipart.MultipartFormDataOutput;
@Path("multipart")
public class Endpoint {
@GET
@Produces(MediaType.MULTIPART_FORM_DATA)
@Path("file")
public MultipartFormDataOutput getFile() {
MultipartFormDataOutput form = new MultipartFormDataOutput();
form.addFormData("person", new Person("John"), MediaType.APPLICATION_JSON_TYPE);
form.addFormData("status", "a status", MediaType.TEXT_PLAIN_TYPE)
.getHeaders().putSingle("extra-header", "extra-value");
return form;
}
}
----

This last approach allows you adding extra headers to the output part.

WARNING: For the time being, returning Multipart data is limited to be blocking endpoints.

==== Handling malformed input
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ public void testSimple() {
.then()
.contentType(ContentType.MULTIPART)
.statusCode(200)
.log().all()
.extract().asString();

assertContains(response, "name", MediaType.TEXT_PLAIN, EXPECTED_RESPONSE_NAME);
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.jboss.resteasy.reactive.common.processor.AdditionalWriters;
import org.jboss.resteasy.reactive.common.processor.EndpointIndexer;
import org.jboss.resteasy.reactive.server.core.multipart.MultipartMessageBodyWriter;
import org.jboss.resteasy.reactive.server.processor.generation.multipart.FormDataOutputMapperGenerator;

import io.quarkus.deployment.GeneratedClassGizmoAdaptor;
import io.quarkus.deployment.annotations.BuildProducer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import javax.ws.rs.core.MediaType;

import org.jboss.resteasy.reactive.RestResponse;
import org.jboss.resteasy.reactive.server.core.multipart.MultipartFormDataOutput;

@Path("/multipart/output")
public class MultipartOutputResource {
Expand Down Expand Up @@ -51,6 +52,20 @@ public RestResponse<MultipartOutputResponse> restResponse() {
return RestResponse.ResponseBuilder.ok(response).header("foo", "bar").build();
}

@GET
@Path("/with-form-data")
@Produces(MediaType.MULTIPART_FORM_DATA)
public RestResponse<MultipartFormDataOutput> withFormDataOutput() {
MultipartFormDataOutput form = new MultipartFormDataOutput();
form.addFormData("name", RESPONSE_NAME, MediaType.TEXT_PLAIN_TYPE);
form.addFormData("custom-surname", RESPONSE_SURNAME, MediaType.TEXT_PLAIN_TYPE);
form.addFormData("custom-status", RESPONSE_STATUS, MediaType.TEXT_PLAIN_TYPE)
.getHeaders().putSingle("extra-header", "extra-value");
form.addFormData("values", RESPONSE_VALUES, MediaType.TEXT_PLAIN_TYPE);
form.addFormData("active", RESPONSE_ACTIVE, MediaType.TEXT_PLAIN_TYPE);
return RestResponse.ResponseBuilder.ok(form).header("foo", "bar").build();
}

@GET
@Path("/string")
@Produces(MediaType.MULTIPART_FORM_DATA)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,22 @@ public void testRestResponse() {
assertContainsValue(response, "num", MediaType.TEXT_PLAIN, "0");
}

@Test
public void testWithFormData() {
String response = RestAssured.get("/multipart/output/with-form-data")
.then()
.log().all()
.contentType(ContentType.MULTIPART)
.statusCode(200)
.extract().asString();

assertContainsValue(response, "name", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_NAME);
assertContainsValue(response, "custom-surname", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_SURNAME);
assertContainsValue(response, "custom-status", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_STATUS);
assertContainsValue(response, "active", MediaType.TEXT_PLAIN, MultipartOutputResource.RESPONSE_ACTIVE);
assertContainsValue(response, "values", MediaType.TEXT_PLAIN, "[one, two]");
}

@Test
public void testString() {
RestAssured.get("/multipart/output/string")
Expand Down
Loading

0 comments on commit 48e52af

Please sign in to comment.