2014-12-04 27 views
14

我有接受文件和JSON對象以下資源(使用Spring 4.05.RELEASE實現):如何在Spring寧靜服務中處理由文件和JSON對象組成的多部分請求?

(PS activityTemplate是可序列化的實體類)

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

,這是形式I我從測試:

<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> 

,這是我的錯誤:

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

那麼應該如何讓資源接受JSON對象作爲多部分請求的一部分,還是應該以不同的方式發送表單?

+0

您可以將json對象作爲請求參數請求。 – 2014-12-04 13:10:32

+0

@DarshanLila使用請求參數時,它將JSON對象看作是一個字符串,並且不會將其轉換爲開箱即用的相應對象。 – Sami 2014-12-04 13:29:33

+0

在簽名('jarFile')中,文件輸入的名稱('file')和註釋的參數名稱之間存在不匹配。這對你的問題有什麼要求嗎? – miw 2015-01-09 19:51:07

回答

2

希望這應該對你有所幫助。您需要在請求中設置邊界以通知HTTP請求。 很簡單;簡要地介紹了多格式可以在下面的鏈接

HTML 4.01 Specification for multipart

下面的例子說明 「的multipart/form-data的」 編碼中找到。 如果JSON對象是「MyJsonObj」,和文件需要被髮送爲「myfile.txt的」,用戶代理可能會發回如下數據:

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-- 

,或者如果你的文件是名稱爲 「Image.gif的」 然後類型的圖像,

您指定boundaryContent-Type header以便服務器知道如何拆分發送的數據。

所以,你基本上需要選擇一個邊界值:

  • 使用,將不會出現在發送給服務器像'AaB03x'的HTTP數據的值。
  • 請保持一致,並在整個請求中使用相同的值。
0

默認的內容類型是'application/octet-stream'。既然你上傳jar文件和JSON內容類型,應在@RequestMapping註解如下設置:

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

該錯誤消息表示沒有的內容類型的多部分/ MIME部分註冊HttpMessageConverter:應用/八位字節流。儘管如此,您的jarFile參數最有可能被正確識別爲application/octet-stream,因此我假設參數映射存在不匹配。

因此,首先嚐試爲參數和表單的輸入元素設置相同的名稱。

另一個問題是JSON上傳爲表單中文本輸入的(常規)值,而不是多部分/ MIME中的單獨部分。因此,沒有與它關聯的內容類型頭文件來發現Spring應該使用JSON解串器。 您可以使用@RequestParam而不是註冊一個特定的轉換器像這樣的回答:JSON parameter in spring MVC controller

1

你還沒有給帕拉姆名稱,以您的@RequestPart S'

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

注意:不要忘了,包括傑克遜映射器的.jar(映射你的JSON來ActivityTemplate)在類路徑的文件。

22

這花了我兩天爲我工作!

客戶端(角):

$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; 
     } 
     }; 

春季(引導):

@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

幫助我理清了我的問題..非常感謝@ user3207391 – sahil 2015-05-08 10:31:21

+0

此請求消耗「multipart/form-data」。因此,您還可以在'@ RequestMapping'中指定'consumes = MediaType.MULTIPART_FORM_DATA_VALUE'以使其顯式化。 – naXa 2017-05-24 11:30:01

0

無法更改您的

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

@RequestMapping(value="/create", 
       method=RequestMethod.POST, consumes ={"multipart/form-data"}) 
相關問題