2012-01-18 14 views
6

È necessario creare un gestore di caricamento file come servizio Web REST con CXF. Sono stato in grado di caricare un singolo file con i metadati utilizzando il codice simile al seguente:Caricamento di più file e metadati con CXF

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

Ora ho bisogno di aggiungere il supporto per il caricamento di più file nella stessa richiesta. In questo caso, invece di un allegato con il tipo di contenuto image/jpeg, ricevo un allegato con il tipo di contenuto multipart/mixed, che a sua volta contiene i singoli allegati image/jpeg di cui ho bisogno.

Ho visto esempi per il caricamento di più oggetti JSON o JAXB con metadati, ma non sono riuscito a ottenere nulla per lavorare con dati di immagine binaria. Ho provato a utilizzare MultipartBody direttamente, ma restituisce solo l'allegato multipart/mixed, non gli allegati image/jpeg incorporati al suo interno.

Esiste un modo per analizzare in modo ricorsivo un allegato multipart/mixed per ottenere gli allegati incorporati? Ovviamente posso ottenere il flusso di input dell'allegato multipart/mixed e analizzare i file personalmente, ma spero che esista un modo migliore.

UPDATE

Questo sembra kludgey, ma il seguente pezzo di codice è abbastanza buono per ora. Mi piacerebbe vedere un modo migliore però.

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

hai provato a definire il parametro come finale @Multipart ("immagine") Lista immagini o è più un problema con i tipi di contenuto? – AxelTheGerman

+0

@axel Se aggiungo un'annotazione Multipart all'elenco degli allegati, CXF passa semplicemente un valore nullo. Devo lasciarlo senza decorazioni per ottenere le immagini. –

risposta

0

Ho creato un servizio simile per caricare più immagini. La mia applicazione sia simile alla seguente (forse aiuta)

@Consumes({MediaType.MULTIPART_FORM_DATA,"multipart/mixed" }) 
public Response uploadImages(final List<Attachment> attachments) { 

    Map<String, InputStream> imageMap = new HashMap<String, InputStream>(); 

    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; 

} 

se qualcuno preferisce array bye al posto di ingresso ruscelli, può essere convertita facilmente usando questo metodo di supporto

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