2015-01-21 19 views
6

Ho bisogno di creare un metodo in Spring MVC in grado di gestire sia le richieste JSON che quelle Multipart.Servizio REST che può utilizzare sia JSON che Multipart Form

Questa è la firma del mio metodo:

@RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST) 
public @ResponseBody void uploadImage(final ImageDTO image) 

classe ImageDTO appare come segue:

public class ImageDTO { 
    private String imageUrl; 
    private Long imageId; 
    private MultipartFile image; 

    public String getImageUrl() { 
    return imageUrl; 
    } 

    public void setImageUrl(final String url) { 
    this.imageUrl = url; 
    } 

    public Long getImageId() { 
    return imageId; 
    } 

    public void setImageId(final Long imageId) { 
    this.imageId = imageId; 
    } 

    public MultipartFile getImage() { 
    return image; 
    } 

    public void setImage(MultipartFile image) { 
    this.image = image; 
    } 
} 

Quindi lo scenario è che ho bisogno di sostenere due scenari: 1. immagine fino carico dalla forma , dove Content-Type è multipart-form (tutti i membri DTO non sono null) 2. Caricamento immagine usando JSON, utilizzando SOLO l'imageUrl. In questo caso, il corpo della richiesta si presenta così:

{ 
    "imageId":"1236", 
    "imageUrl":"http://some.image.url", 
    "image":null 
} 

L'implementazione corrente gestisce bene la richiesta più parti, ma quando si invia il JSON, l'oggetto ImageDTO contiene NULL in tutti i suoi membri.

È possibile utilizzare lo stesso metodo per gestire entrambi i tipi di contenuto?

Grazie.

risposta

1

Per ricevere JSON è necessario marcare ImageDTO discussione con @RequestBody

@RequestMapping(value = { "/upload_image" }, method = RequestMethod.POST) 
public @ResponseBody void uploadImage(final @RequestBody ImageDTO image) 
+0

Grazie. Ho già provato questo, questo fa sì che il JSON funzioni, ma quando invio la richiesta in formato multipart non riesce e l'errore dice che il tipo di contenuto in formato multipart non è supportato. –

+2

Sì, non è possibile farlo direttamente. – shazin

+0

Capisco. Grazie mille. –

1

aveva affrontato una situazione simile, ed ecco cosa mi piacerebbe venire con. Entrambi i metodi non sono così puliti, ma funzionano perfettamente. È necessario inviare una richiesta di multipartdal client:

Nota: Il tipo di dato della variabile per contenere il file è InputStream. È necessario modificare di conseguenza

  1. Questo è utile nei casi non si è a conoscenza del numero di file che stanno ricevendo in voi richiesta.

    // imports 
    import org.apache.commons.fileupload.servlet.ServletFileUpload; 
    import org.apache.commons.fileupload.FileItem; 
    import org.apache.commons.fileupload.disk.DiskFileItemFactory; 
    
    // code flow 
    // HttpServletRequest request 
    final FileItemFactory factory = new DiskFileItemFactory(); 
    final ServletFileUpload fileUpload = new ServletFileUpload(factory); 
    List items = null; 
    private Map<String, InputStream> fileMap = new HashMap<String, InputStream>(); 
    
    if (ServletFileUpload.isMultipartContent(request)) { 
    
        // get the request content and iterate through 
        items = fileUpload.parseRequest(request); 
    
        if (items != null) { 
         final Iterator iter = items.iterator(); 
         while (iter.hasNext()) { 
          final FileItem item = (FileItem) iter.next(); 
          final String fieldName = item.getFieldName(); 
          final String fieldValue = item.getString(); 
          // this is for non-file fields 
          if (item.isFormField()) { 
           switch (fieldName) { 
            case "imageId" : 
            // set inside your DTO field 
            break; 
    
            // do it for other fields 
           } 
    
          } else { 
           // set the image in DTO field 
          } 
         } 
        } 
    } 
    
  2. In questo caso, si dovranno fare i conti con il numero fisso di forma campi. Avevo implementato nel metodo di resto come segue:

    @Path("/upload") 
    @POST 
    @Consumes(MediaType.MULTIPART_FORM_DATA) 
    public ResponseDTO upload(FormDataMultiPart multiPartData) { 
    
         // non-file fields 
         final String imageId = multiPartData.getField("imageId").getValue(); 
    
         // for file field  
         final FormDataBodyPart imagePart = multiPartData.getField("image"); 
         final ContentDisposition imageDetails= imagePart.getContentDisposition(); 
         final InputStream imageDoc = imagePart.getValueAs(InputStream.class); 
    
         // set the retrieved content in DTO 
    } 
    
+0

Sembra Jax-Rs non Spring MVC – shazin

+0

Se ho capito bene, questo richiederà che la richiesta sia sempre con tipo di contenuto "multipart-form". Mi chiedo se sia possibile rendere il metodo in grado di gestire sia la forma multipart, ma anche json nella richiesta. –

+0

Sì, ciò richiederà una richiesta di modulo in più parti. Non è possibile inviare il contenuto del file in una richiesta JSON. –

0

Ho avuto lo stesso risultato - NULL a tutti i membri DTO fino a quando ho introdotto l'annotazione @ModelAttribute.Ora tutto funziona bene, ecco il codice di lavoro:

metodo controller:

@RequestMapping(value = "/save", method = RequestMethod.POST, 
     consumes = { "multipart/form-data" }) 
public void create(@Valid @ModelAttribute("entryForm") final EntryDTO entryDTO, 
     final BindingResult validationResult) throws FormValidationError { 
    validate(entryDTO, validationResult); 
    entryService.save(entryDTO); 
} 

DTO:

public class EntryDTO { 

    private String phrase; 

    private String translation; 

    private MultipartFile imageFile; 

} 

Modulo:

<form method="post" name="entryForm" action="http://localhost:8080/save" 
     enctype="multipart/form-data"> 
    <p><input type="text" name="phrase" value="test"/> phrase</p> 
    <p><input type="text" name="translation" value="тест"/> translation</p> 
    <p><input type="file" name="imageFile"/></p> 
    <p><input type="submit"/></p> 
</form> 

Nota: il modulo è denominato "entryForm" e corrispondentemente @ModelAttribute ("entryForm").

Problemi correlati