1

I need to invoke a remote REST interface handler and submit it a file in request body. Please note that I don't control the server. I cannot change the request to be multipart, the client has to work in accordance to external specification.

So far I managed to make it work like this (omitting headers etc. for brevity):

byte[]  data = readFileCompletely ();
client.target (url).request ().post (Entity.entity (data, "file/mimetype"));

This works, but will fail with huge files that don't fit into memory. And since I have no restriction on filesize, this is a concern.

Question: is it somehow possible to use streams or something similar to avoid reading the whole file into memory?

If possible, I'd prefer to avoid implementation-specific extensions. If not, a solution that works with RESTEasy (on Wildfly) is also acceptable.

6
  • What's the actual media type? application/octet-stream has a writer that can handle InputStream. Or I think StreamingOutput even works on the client side for all media types, though I haven't tried it, but I imagine it should work Commented Jul 4, 2016 at 14:42
  • It fully depends on file contents, but usually will be "application/pdf". Commented Jul 4, 2016 at 14:43
  • I'd try the StreamingOutput. I think I've used it before on the client side. I can't remember. Commented Jul 4, 2016 at 14:44
  • Have you tried simply putting the InputStream into the entity Entity.entity(inputStream, "application/octetstream"); AFAIK Jersey can handle it so I guess RestEasy should too. Commented Jul 4, 2016 at 14:46
  • I kinda have a feeling that InputStream would actually work for any media type also. Have you tried InputStream? Commented Jul 4, 2016 at 14:58

2 Answers 2

1

ReastEasy as well as Jersey support InputStream out of the box so simply use Entity.entity(inputStream, "application/octet-stream"); or whatever Content-Type header you want to set.

Sign up to request clarification or add additional context in comments.

Comments

0

You can go low-level and construct the HTTP request using a library such as the plain java.net.URLConnection.

I have not tried it myself but there is example code which reads a local file and writes it to the request stream without loading it into a byte array.

Upload files from Java client to a HTTP server

Of course this solution requires more manual coding but it should work (unless java.net.URLConnection loads the whole file into memory)

2 Comments

Yeah, might be that I have to use sth. like this in the end.
Interesting, I now made more tests. While passing FileInputStream (or even just File itself) to Entity.entity() works, what really transmitted over HTTP is a string "data:application/octet-stream;base64,...". I.e. not raw file contents which I hoped for. Server I cooperate with seems to handle that just fine, but it looks strange to me. Why not just put file contents raw? Encoding it first blows up size by a third and requires some extra processing from the server. And I don't see any benefits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.