Dropwizard Jersey Client Sample

5.5k views Asked by At

Dropwizard official documentation jersey Client isn't testable, someone have a dropwizard jersey client sample?

2

There are 2 answers

0
impulso On BEST ANSWER

I found implementing my client in Dropwizard a little bit challenging as well. So I would like to contribute just in case anyone encounters this problem. This is a client in Dropwizard (v1.0.5) that invokes a POST web service using Multipart. The client is accessed via web service as well using GET.

Dependencies in my pom.xml:

<dependencies>
<dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-core</artifactId>
    <version>${dropwizard.version}</version>
</dependency>
<dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-assets</artifactId>
    <version>${dropwizard.version}</version>
</dependency>
<dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-forms</artifactId>
    <version>${dropwizard.version}</version>
</dependency>
<dependency>
    <groupId>io.dropwizard</groupId>
    <artifactId>dropwizard-client</artifactId>
    <version>${dropwizard.version}</version>
</dependency>

</dependencies>

Here my Dropwizard Application (Client2PostApplication.java):

    public class Client2PostApplication extends Application<Client2PostConfiguration> {
    public static void main(String[] args) throws Exception {
        new Client2PostApplication().run(args);
    }

    @Override
    public void initialize(Bootstrap<Client2PostConfiguration> bootstrap) {
        bootstrap.addBundle(new MultiPartBundle());
    }

    @Override
    public void run(Client2PostConfiguration configuration,
                Environment environment) throws Exception {

        environment.jersey().register(MultiPartFeature.class);
        JerseyClientConfiguration conf = configuration.getJerseyClientConfiguration();

        conf.setChunkedEncodingEnabled(false);

        final Client client = new JerseyClientBuilder(environment).using(conf).build(getName());
        environment.jersey().register(new Client2Post(client));
        environment.jersey().register(new MyPostResource());       
    }
}

Here my Configuration (Client2PostConfiguration.java):

public class Client2PostConfiguration extends Configuration {

    @Valid
    @NotNull
    private JerseyClientConfiguration jerseyClient = new JerseyClientConfiguration();

    @JsonProperty("jerseyClient")
    public JerseyClientConfiguration getJerseyClientConfiguration() {
        return jerseyClient;
    }
}

And now, the post web service (MyPostResource.java):

@Path("/testpost")

public class MyPostResource {

    public MyPostResource() {

    }

    @POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Timed
    public String test(
        @FormDataParam("foo") String testData) throws IOException {
        return testData;
    }
}

And finally, the client (Client2Post.java):

@Produces(MediaType.TEXT_PLAIN)
@Path("/client")
public class Client2Post {

    private Client client;

    public Client2Post(Client client) {
        this.client = client;
    }

    @GET
    @Path("/test")
    public String testPost() {

    final Invocation.Builder request = client.target("http://localhost:8080/testpost").register(MultiPartFeature.class).request();

    final FormDataMultiPart entity = new FormDataMultiPart()
            .field("foo", "bar");

    final String response = request.post(Entity.entity(entity, entity.getMediaType()), String.class);

    return response;

    }
}

The complete source code can be downloaded from here.

1
Rowan On

The Dropwizard manual gives code examples of how to add configuration for and then build a Jersey client in your app.

The Jersey documentation itself has details (and code examples) of how to use a Client to make a request.

As a slightly unrelated suggestion, I like to write a client for each service I write (as a separate maven module) that other libraries (and indeed other Dropwizard services) can then use to communicate with the service. That lets me encapsulate all the details of interacting with the service (e.g. how to construct paths, what classes to marshal the results as) in one place, so I can present a nice, simple POJO interface to the outside world. Note this means sharing model representations between the client and the service, pretty much as per the suggestion in the Dropwizard docs.

An example client might looks something like the following:

public class MyClient {
    private static final String RESOURCE_PATH = "resource-path";
    private static final DateTimeFormatter FORMATTER = ISODateTimeFormat.dateTimeNoMillis();

    private final Client jerseyClient;
    private final String targetUrl;

    public MyClient(Client jerseyClient, String targetUrl) {
        this.jerseyClient = jerseyClient;
        this.targetUrl = targetUrl;
    }

    public List<CustomModelClass> getSomeResource(Interval someParam) {
        WebTarget webResource = jerseyClient.target(targetUrl).path(RESERVATIONS_PATH);

        webResource = webResource.queryParam("startTime", someParam.getStart().toString(FORMATTER));
        webResource = webResource.queryParam("endTime", someParam.getEnd().toString(FORMATTER));

        Invocation.Builder invocationBuilder = webResource.request(MediaType.APPLICATION_JSON_TYPE);
        Response response = invocationBuilder.get();

        return response.readEntity(new GenericType<List<CustomModelClass>>(){});
    }
}