Skip to content

Commit

Permalink
Jersey example with multipart file upload support (#1555)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkountis authored May 12, 2021
1 parent b88e4fa commit 4d0ed54
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
3 changes: 2 additions & 1 deletion servicetalk-examples/http/jaxrs/build.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2019 Apple Inc. and the ServiceTalk project authors
* Copyright © 2019, 2021 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@ dependencies {
implementation project(":servicetalk-data-jackson-jersey")
implementation project(":servicetalk-http-netty")
implementation project(":servicetalk-http-router-jersey")
implementation "org.glassfish.jersey.media:jersey-media-multipart:$jerseyVersion"
implementation "org.slf4j:slf4j-api:$slf4jVersion"

runtimeOnly "org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Apple Inc. and the ServiceTalk project authors
* Copyright © 2018, 2021 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,9 +15,14 @@
*/
package io.servicetalk.examples.http.jaxrs;

import org.glassfish.jersey.media.multipart.MultiPartFeature;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;

import static java.util.Arrays.asList;
import static java.util.Collections.singleton;

/**
Expand All @@ -26,6 +31,10 @@
public class HelloWorldJaxRsApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
return singleton(HelloWorldJaxRsResource.class);
return new HashSet<>(asList(
MultiPartFeature.class,
HelloWorldJaxRsResource.class
)
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright © 2018 Apple Inc. and the ServiceTalk project authors
* Copyright © 2018, 2021 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,10 +17,14 @@

import io.servicetalk.buffer.api.Buffer;
import io.servicetalk.buffer.api.BufferAllocator;
import io.servicetalk.buffer.api.CompositeBuffer;
import io.servicetalk.concurrent.api.Publisher;
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.transport.api.ConnectionContext;

import org.glassfish.jersey.media.multipart.FormDataParam;

import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
Expand All @@ -36,10 +40,12 @@
import javax.ws.rs.core.Response;

import static io.servicetalk.concurrent.api.Publisher.from;
import static io.servicetalk.concurrent.api.Publisher.fromInputStream;
import static java.lang.Math.random;
import static java.util.Collections.singletonMap;
import static java.util.concurrent.TimeUnit.SECONDS;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA;
import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
import static javax.ws.rs.core.Response.accepted;
import static javax.ws.rs.core.Response.ok;
Expand Down Expand Up @@ -145,6 +151,33 @@ public Single<Buffer> hello(final Single<Buffer> who,
.addBuffer(allocator.fromAscii("!")));
}

/**
* Resource that relies on multi-part file upload on the consume side, and {@link Publisher} with
* operators for processing it on the produce side.
* <p>
* Test with:
* <pre>
* echo "An empty file" > sample.txt && curl -vF "file=@sample.txt" \
* http://localhost:8080/greetings/multipart-hello
* </pre>
*
* @param ctx the {@link ConnectionContext}.
* @param file the multi-part file contents.
* @return greetings as a {@link Single} {@link Buffer}.
*/
@POST
@Path("multipart-hello")
@Consumes(MULTIPART_FORM_DATA)
@Produces(TEXT_PLAIN)
public Single<Buffer> multipartHello(@Context final ConnectionContext ctx,
@FormDataParam("file") InputStream file) {
final BufferAllocator allocator = ctx.executionContext().bufferAllocator();
return from(allocator.fromAscii("Hello multipart! Content: "))
.concat(fromInputStream(file).map(allocator::wrap))
.collect(allocator::newCompositeBuffer,
(collector, item) -> ((CompositeBuffer) collector).addBuffer(item));
}

/**
* Resource that only relies on {@link Single}/{@link Publisher} for consuming and producing data,
* and returns a JAX-RS {@link Response} in order to set its status.
Expand Down

0 comments on commit 4d0ed54

Please sign in to comment.