I need to create a file upload handler as a REST web service with CXF. I've been able to upload a single file with metadata using code like the following:
@POST
@Path("/uploadImages")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadImage(@Multipart("firstName") String firstName,
@Multipart("lastName") String lastName,
List<Attachment> attachments) {
for (Attachment att : attachments) {
if (att.getContentType().getType().equals("image")) {
InputStream is = att.getDataHandler().getInputStream();
// read and store image file
}
}
return Response.ok().build();
}
Now I need to add support for uploading multiple files in the same request. In this case, instead of an attachment with image/jpeg
content type, I get an attachment with multipart/mixed
content type, which itself contains the individual image/jpeg
attachments that I need.
I've seen examples for uploading multiple JSON or JAXB objects with metadata, but I have not been able to get anything to work with binary image data. I have tried using the MultipartBody directly, but it only returns the multipart/mixed
attachment, not the image/jpeg
attachments embedded within it.
Is there a way to recursively parse a multipart/mixed
attachment to get the embedded attachments? I can of course get the input stream of the multipart/mixed
attachment, and parse out the files myself, but I'm hoping there is a better way.
UPDATE
This seems kludgey, but the following bit of code is good enough for now. I would love to see a better way though.
for (Attachment att : attachments) {
LOG.debug("attachment content type: {}", att.getContentType().toString());
if (att.getContentType().getType().equals("multipart")) {
String ct = att.getContentType().toString();
Message msg = new MessageImpl();
msg.put(Message.CONTENT_TYPE, ct);
msg.setContent(InputStream.class, att.getDataHandler().getInputStream());
AttachmentDeserializer ad = new AttachmentDeserializer(msg, Arrays.asList(ct));
ad.initializeAttachments();
// store the first embedded attachment
storeFile(msg.getContent(InputStream.class));
// store remaining embedded attachments
for (org.apache.cxf.message.Attachment child : msg.getAttachments()) {
storeFile(child.getDataHandler().getInputStream());
}
}
else if (att.getContentType().getType().equals("image")) {
storeFile(att.getDataHandler().getInputStream());
}
}
I've build a similar service to upload multiple images. My implementation looks like the following (maybe it helps)
if someone prefers bye arrays instead of input streams, it can be converted easily using this helper method