1

I want to PUT, via binary, to an endpoint that can consume one of many possible mimetypes. Specifically, I am communicating with an Apache Tika server, which could take, say, a PDF or a Word .docx file.

I've set up a client proxy interface that I can hardcode, say, the .docx mimetype:

public interface TikaClient {
    @PUT
    @Path("tika")
    @Consumes("application/vnd.openxmlformats-officedocument.wordprocessingml.document")
    Response putBasic(byte[] body);
}

And this will work when I call it:

ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget target = client.target(url);
TikaClient tikaClient = target.proxy(TikaClient.
Response response = tikaClient.putBasic(binaryFileData);

....But that endpoint specifically could also take a "text/plain" or "application/pdf".

I believe I can specify multiple @Consumes options: @Consumes({"text/plain", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"})

But it doesn't seem to pick the right one, and I don't know how to tell it which one the file in question is.

Offlein
  • 665
  • 6
  • 22

1 Answers1

2

You can add multiple MediaTypes as you already mentioned. If the server accepts more than one MediaType he has to negotiate with the client which one should be used. The client should send a Content-Type header like Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document.

For adding a Content-Type header with the proxy framework you have to options:

  • Adding the @HeaderParam("Content-Type") as parameter to your putBasicmethod.
  • Registering a ClientRequestFilter which will set this header.

I don't know why but with the proxy framework this was not working for me. It is working if you use the standard client way:

client.target(url)
.request()
.put(Entity.entity(binaryFileData,
  MediaType.valueOf("application/vnd.openxmlformats-officedocument.wordprocessingml.document")));

The server should now pick the MediaType you are using.

lefloh
  • 10,653
  • 3
  • 28
  • 50
  • Indeed! This worked on mine! I'm somewhat new to Java, so I'm a little confused about two things: (1) how/why we pass an annotation (@HeaderParam) into the putBasic method, and (2) When you say register a "ClientRequestFilter", you mean basically write a class that implements ClientRequestFilter, right? [A la this post](http://stackoverflow.com/questions/21763700/how-to-set-http-header-in-resteasy-3-0-client-framework-with-resteasyclientbuil)? Do you know of documentation explaining what is happening during question (a)? – Offlein May 28 '15 at 17:51
  • 1
    Correct. The `ClientRequestFilter` is described in the linked post. Using the `@HeaderParam` would change your method signature like this: `Response putBasic(@HeaderParam("Content-Type") String contentType, byte[] body)`. – lefloh May 29 '15 at 05:14