Skip to content

Commit

Permalink
Add multipart support to specification
Browse files Browse the repository at this point in the history
  • Loading branch information
jim-krueger committed Jun 12, 2024
1 parent 6023953 commit 3e045f4
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 1 deletion.
59 changes: 58 additions & 1 deletion spec/src/main/asciidoc/clientexamples.asciidoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2017-2021 Contributors to the Eclipse Foundation
// Copyright (c) 2017 Contributors to the Eclipse Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -282,3 +282,60 @@ public interface BadInterfaceThree {
All three interfaces will result in a RestClientDefinitionException.

As previously mentioned, specifying the same header name in multiple `@ClientHeaderParam` annotations on the same target will result in a RestClientDefinitionException. Likewise, specifying multiple compute methods in the `@ClientHeaderParam` value attribute will result in a RestClientDefinitionException.

=== Processing Multipart Data

The `multipart/form-data` media type enables requests to send multiple entities (parts) as a single entity using `jakarta.ws.rs.core.EntityPart` objects.

MicroProfile Multipart Rest Clients are defined as Java interfaces. For example:

[source, java]
----
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.MULTIPART_FORM_DATA)
@Path("/test-app")
public interface MultiPartClient extends AutoCloseable {
@POST
@Path("upload/")
void uploadFile(List<EntityPart> entityParts) throws IOException;
}
----

Example code utilizing this interface:

[source, java]
----
public void uploadMultipleFiles() throws Exception {
try (MultiPartClient client = RestClientBuilder.newBuilder()
.baseUri(uri)
.build(MultiPartClient.class)) {
final Map<String, byte[]> entityPartContent = new LinkedHashMap<>(2);
try (InputStream in = MultiPartClientTest.class
.getResourceAsStream("/multipart/test-file1.txt")) {
entityPartContent.put("test-file1.txt", in.readAllBytes());
}
try (InputStream in = MultiPartClientTest.class
.getResourceAsStream("/multipart/test-file2.txt")) {
entityPartContent.put("test-file2.txt", in.readAllBytes());
}
final List<EntityPart> files = entityPartContent.entrySet()
.stream()
.map((entry) -> {
try {
return EntityPart.withName(entry.getKey())
.fileName(entry.getKey())
.content(entry.getValue())
.mediaType(MediaType.APPLICATION_OCTET_STREAM_TYPE)
.build();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
})
.collect(Collectors.toList());
client.uploadFile(files);
}
}
----

Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public void testPriorities() throws Exception {
assertEquals("TestClientRequestFilterPriority4", result.requestsInvoked.get(1).getSimpleName());
assertEquals("TestClientRequestFilterPriority1", result.requestsInvoked.get(2).getSimpleName());
assertEquals("TestClientRequestFilterPriority3", result.requestsInvoked.get(3).getSimpleName());
// Per the Jakarta Rest specification, the order of priorities between Client
// request and response filters are reversed.
assertEquals("TestClientResponseFilterPriority2", result.responsesInvoked.get(0).getSimpleName());
assertEquals("TestClientResponseFilterPriority4", result.responsesInvoked.get(1).getSimpleName());
assertEquals("TestClientResponseFilterPriority1", result.responsesInvoked.get(2).getSimpleName());
Expand Down

0 comments on commit 3e045f4

Please sign in to comment.