Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jersey REST client - multipart creation - not from File object

I guess there is no other way for creating a FileDateBodyPart than providing a File object:

public FileDataBodyPart(String name, File fileEntity)

But in my case what I have is a byte[] and I don't want to convert it to a file and store on a filesystem.

Is there any other way of generating a multipart (while uploading a file) from an array of byte, inputstream... in the worst case using other client library?

UPDATE: Here is the working code (but I want to use byte[] instead of File):

FileDataBodyPart filePart = new FileDataBodyPart("attachment", new File("C:/TEMP/test.txt"));
MultiPart multipart = new FormDataMultiPart().bodyPart(filePart);
Invocation.Builder invocationBuilder = webTarget.request().accept(MediaType.APPLICATION_JSON);
Response response = invocationBuilder
        .buildPost(Entity.entity(multipart, MediaType.MULTIPART_FORM_DATA))
        .invoke();
like image 474
Mark Avatar asked Sep 12 '17 09:09

Mark


2 Answers

FileDataBodyPart is just a convenience class. It is not the only type you can use to create a body part. If you look at the docs for FormDataMultuPart.bodyPart(), you'll see that it takes as an argument a BodyPart. Check out the Javadocs (search for it; can't find direct link). If you look for BodyPart and traverse the hierarchy, there are a few classes the extend from BodyPart, like FormDataBodyPart (the most generic) and also StreamDataBodyPart. You could use either.

If you have an InputStream, the easiest way is to use the StreamDataBodyPart. See the javadoc, it has overloaded constructors.

If you MUST use a byte[], then you can just use the more generic FormDataBodyPart

byte[] bytes = "HelloWorld".getBytes(StandardCharsets.UTF_8);
FormDataContentDisposition fdcd = FormDataContentDisposition.name("test")
        .fileName("hello.txt").build();
FormDataBodyPart bodyPart = new FormDataBodyPart(fdcd, bytes, MediaType.TEXT_PLAIN_TYPE);
MultiPart multiPart = new FormDataMultiPart().bodyPart(bodyPart);

Parts should have a Content-Disposition header which give a little information about the part, so the server can handle it properly. The FileDataBodyPart and StreamDataBodyPart would handle the creation of the FormDataContentDisposition internally, that's why they are convenience classes.

like image 68
Paul Samsotha Avatar answered Nov 20 '22 12:11

Paul Samsotha


There's no other way for FileDataBodyPart to not accept a file.

As a workaround, you might want to create a temporary file and delete it once the JVM exits:

byte[] bytes = {1, 2, 3};

File tempFile = File.createTempFile("filename", null);
tempFile.deleteOnExit();

FileOutputStream fos = new FileOutputStream(tempFile);
fos.write(bytes);
fos.close();

FileDataBodyPart filePart = new FileDataBodyPart("attachment", tempFile);
like image 3
Luciano van der Veekens Avatar answered Nov 20 '22 13:11

Luciano van der Veekens