使用CXF上传多个文件和元数据

我需要使用CXF创建一个文件上载处理程序作为REST Web服务。 我已经能够使用以下代码上传包含元数据的单个文件:

@POST @Path("/uploadImages") @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadImage(@Multipart("firstName") String firstName, @Multipart("lastName") String lastName, List 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(); } 

现在我需要添加对在同一请求中上传多个文件的支持。 在这种情况下,我得到一个带有multipart/mixed内容类型的附件,而不是带有image/jpeg内容类型的附件,它本身包含我需要的单个image/jpeg附件。

我已经看到了使用元数据上传多个JSON或JAXB对象的示例,但是我无法使用二进制图像数据。 我已尝试直接使用MultipartBody,但它只返回multipart/mixed附件,而不是其中嵌入的image/jpeg附件。

有没有办法递归解析multipart/mixed附件以获取嵌入的附件? 我当然可以得到multipart/mixed附件的输入流,并自己解析文件,但我希望有更好的方法。

UPDATE

这看起来像kludgey,但是下面的代码现在已经足够好了。 我希望看到更好的方式。

 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()); } } 

我已经构建了一个类似的服务来上传多个图像。 我的实现看起来如下(也许它有帮助)

 @Consumes({MediaType.MULTIPART_FORM_DATA,"multipart/mixed" }) public Response uploadImages(final List attachments) { Map imageMap = new HashMap(); for (Attachment attachment : attachments) { String imageName = attachment.getContentDisposition().getParameter("filename"); if (imageName == null) { imageName = UUID.randomUUID().toString(); } InputStream image = attachment.getDataHandler().getInputStream(); imageMap.put(imageName, image); } return imageMap; } 

如果有人喜欢再见数组而不是输入流,可以使用这个助手方法轻松转换它

 private static byte[] extractByteArray(final InputStream inputStream) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); byte[] dataChunk = new byte[1024 * 16]; int numRead = 0; while (numRead != -1) { numRead = inputStream.read(dataChunk, 0, dataChunk.length); if (numRead != -1) { buffer.write(dataChunk, 0, numRead); } } buffer.flush(); return buffer.toByteArray(); }