2014-12-04 9 views
14

Ho la seguente risorsa (implementato utilizzando primavera 4.05.RELEASE), che accetta un file e un oggetto JSON:Come elaborare una richiesta multipart composta da un file e un oggetto JSON nel servizio restful di Spring?

(PS activityTemplate è una classe di entità serializzabile)

... 
@RequestMapping(value="/create", method=RequestMethod.POST) 
public @ResponseBody ActivityTemplate createActivityTemplate(
     @RequestPart ActivityTemplate activityTemplate, @RequestPart MultipartFile jarFile) 
{ 
    //process the file and JSON 
} 
... 

e questa è la forma che sto testando da:

<form method="POST" enctype="multipart/form-data" 
    action="http://localhost:8080/activityTemplates/create"> 
    JSON: <input type="text" name="activityTemplate" value='/* the JSON object*/'><br /> 

    File to upload: <input type="file" name="file"> 
    <input type="submit" value="Upload"> 
</form> 

e questo è l'errore che ottengo:

There was an unexpected error (type=Unsupported Media Type, status=415). 
Content type 'application/octet-stream' not supported 

Quindi, come devo fare in modo che la risorsa accetti l'oggetto JSON come parte della richiesta multipart o dovrei inviare il modulo in un modo diverso?

+0

è possibile ottenere oggetto json come parametro di richiesta per la richiesta. –

+0

@DarshanLila con l'utilizzo del parametro request, vede l'oggetto JSON come una stringa e non lo converte nell'oggetto corrispondente fuori dalla scatola. – Sami

+0

C'è una mancata corrispondenza tra il nome dell'ingresso del file ('file') e il nome del parametro annotato nella firma (' jarFile'). Questo deve fare qualcosa con il tuo problema? – miw

risposta

2

Spero che questo dovrebbe aiutarti. È necessario impostare il limite nella richiesta per informare la richiesta HTTP. è semplice; Una breve introduzione al formato multipart possono essere trovate nel link sottostante

HTML 4.01 Specification for multipart

Il seguente esempio illustra "multipart/form-data" encoding. Se l'oggetto JSON è "MyJsonObj", e il file che devono essere inviare è "myfile.txt", l'agente utente potrebbe inviare di nuovo i seguenti dati:

Content-Type: multipart/form-data; boundary=MyBoundary 

--MyBoundary 
Content-Disposition: form-data; name="myJsonString" 
Content-Type: application/json 

MyJsonObj //Your Json Object goes here 
--MyBoundary 
Content-Disposition: form-data; name="files"; filename="myfile.txt" 
Content-Type: text/plain 

... contents of myfile.txt ... 
--MyBoundary-- 

o se il vostro file è di tipo immagine con nome "image.gif" poi,

Si specifica boundary in il Content-Type header in modo che il server sappia come dividere i dati inviati.

Quindi, è fondamentalmente necessario selezionare un valore limite per:

  • Utilizzare un valore che non appare nei dati HTTP inviati al server come 'AaB03x'.
  • Essere coerenti e utilizzare lo stesso valore su tutta la richiesta.
0

Il tipo di contenuto predefinito è 'application/octet-stream'. Dal momento che si sta caricando file jar e JSON il tipo di contenuto deve essere impostato nel @RequestMapping annotazioni come segue:

@RequestMapping(value="/create", method=RequestMethod.POST, headers="content-type=application/json,application/java-archive") 
0

Il messaggio di errore indica che non v'è alcuna HttpMessageConverter registrato per un multi-parte/parte MIME di tipo di contenuto: application/octet-stream. Tuttavia, il tuo parametro jarFile è probabilmente identificato correttamente come application/octet-stream, quindi suppongo che ci sia una mancata corrispondenza nella mappatura dei parametri.

Quindi, provare innanzitutto a impostare lo stesso nome per il parametro e l'elemento di input del modulo.

Un altro problema è che il JSON viene caricato come valore (regolare) di un input di testo nel modulo, non come una parte separata nel multi-part/MIME. Quindi non è presente un'intestazione del tipo di contenuto ad essa associata per scoprire che Spring dovrebbe utilizzare il deserializzatore JSON. È possibile utilizzare @RequestParam invece e registrare un convertitore specifico come in questa risposta: JSON parameter in spring MVC controller

1

Non hai dato i nomi param al vostro @RequestPart s?

public @ResponseBody ActivityTemplate createActivityTemplate(
    @RequestPart("activityTemplate") ActivityTemplate activityTemplate, @RequestPart("file") MultipartFile jarFile) 
{ 
    //process the file and JSON 
} 

Nota: non dimenticare di includere il jackson mapper .jar (mappe La vostra JSON per ActivityTemplate) file nel classpath.

22

Mi ci sono voluti due giorni per lavorare!

cliente (angolare):

$scope.saveForm = function() { 
     var formData = new FormData(); 
     var file = $scope.myFile; 
     var json = $scope.myJson; 
     formData.append("file", file); 
     formData.append("ad",JSON.stringify(json));//important: convert to string JSON! 
     var req = { 
     url: '/upload', 
     method: 'POST', 
     headers: {'Content-Type': undefined}, 
     data: formData, 
     transformRequest: function (data, headersGetterFunction) { 
      return data; 
     } 
     }; 

Primavera (Boot):

@RequestMapping(value = "/upload", method = RequestMethod.POST) 
    public @ResponseBody 
    Advertisement storeAd(@RequestPart("ad") String adString, @RequestPart("file") MultipartFile file) throws IOException { 

     Advertisement jsonAd = new ObjectMapper().readValue(adString, Advertisement.class); 
//do whatever you want with your file and jsonAd 
+0

Aiutami a risolvere anche il mio problema .. Grazie mille @ user3207391 – sahil

+0

Questa richiesta consuma "multipart/form-data". Quindi puoi anche specificare 'consumes = MediaType.MULTIPART_FORM_DATA_VALUE' in' @ RequestMapping' per renderlo esplicito. – naXa

0

non Potrebbe cambiare la vostra

@RequestMapping(value="/create", method=RequestMethod.POST) 

a

@RequestMapping(value="/create", 
       method=RequestMethod.POST, consumes ={"multipart/form-data"}) 
Problemi correlati