2014-12-11 72 views
8

我目前正在嘗試編寫一個接受文件上傳的ReST方法。當用戶提交文件時,我也希望他們添加一個描述以及一些其他與文件內容有關的元數據(例如,與文件內容相關的「類型」)。我使用Spring MVC的控制器使用Spring 4我可以在Spring Rest方法中混合媒體類型嗎?

這是我想要做的一個例子:

@RequestMapping(value = "/file", method = RequestMethod.POST) 
public @ResponseBody 
ResponseEntity<MyFileDTO> uploadCustomAnnotationFile(
     @RequestParam("file") MultipartFile uploadFile, 
     @RequestBody MyFileDetailsDTO fileDetails) { 
    log.debug("This is working!"); 
} 

但是,如果我嘗試調用通過揚鞭UI這種方法,我得到一個不支持的媒體類型的異常:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundarycAbgNBTQ09GQTBif' not supported 

我懷疑我不能在1個請求混合應用/ JSON和多部分/格式數據?

更新: 基於zeroflagL的響應和跟隨提供的特定於我正在嘗試執行的文檔的鏈接,並使用@RequestPart而不是@RequestBody,我取得了很小的進展,但這仍然不起作用。

新方法簽名:

@RequestMapping(value = "/file", method = RequestMethod.POST) 
public @ResponseBody 
ResponseEntity<MyFileDTO> uploadCustomAnnotationFile(
     @RequestPart MultipartFile uploadFile, 
     @RequestPart MyFileDetailsDTO fileDetails) { 
    log.debug("This is working!"); 
} 

新的異常:

2014-12-11 09:21:45.237 [http-nio-8443-exec-8] ERROR c.i.h.c.ControllerExceptionHandler [ControllerExceptionHandler.groovy:58] - Controller Exception 
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'fileDetails' is not present. 

在此先感謝, 湯妮雅

+1

請注意,如果您的@Controller類在@ RequestMapping的「consumes」屬性中聲明瞭錯誤的端點格式,例如如果您聲明'consumes = {「application/json」},則也會拋出'HttpMediaTypeNotSupportedException '在課堂上,但是有一個終端需要使用「multipart/form-data」。 – lanoxx 2016-07-31 20:07:55

回答

1

Spring documentation明確解釋怎樣做。

mix application/json和multipart/form-data的想法是錯誤的,因爲application/json將是multipart(sic!)請求的一部分。

WebKitFormBoundary讓我覺得你試圖從你的瀏覽器發送一個AJAX請求,我不知道你是否真的發送JSON。 AFAIK不可能像Spring文檔中顯示的那樣顯式地添加(實際)JSON部分。也許你可以向我們展示客戶端代碼。

無論如何,你不能使用@RequestBody,因爲這將包括你想上傳的文件。你將不得不使用@RequestPart。如果您發送表單數據 - 而不是JSON - 與文件一起發送,則根本不需要任何註釋。

+0

還沒有客戶代碼。正如我在原帖中所述,我正在使用Swagger UI來測試我的ReST端點。 我一直在使用Swing註釋一段時間,而'@ RequestBody'則是如何配置我的ReST端點以接受/期望請求的「主體」中的JSON數據。即使它與查詢參數和/或路徑參數結合使用,我以前從未遇到過使用'@ RequestBody'的問題。 但是,結合MultipartFile ...現在是一個問題。該方法不會期望該參數的JSON數據,並引發無效媒體類型的異常。 – 2014-12-11 17:04:56

+0

@TonyaOhrel Swagger UI在瀏覽器中運行,所以如果您的最終客戶端不在瀏覽器中運行,它就會有所不同。在這種情況下,您也不需要任何註釋。 – zeroflagL 2014-12-12 08:43:59

3

您可以在Spring REST方法中混合使用媒體類型。 @ zeroflagL /答案也許正確。但@RequestPart工作正常。這裏是我的代碼,它與你的沒什麼不同

@RequestMapping(value = "/interface/member/v1/register.do", method = RequestMethod.POST) 
@ResponseBody 
public RegisterResponse register(@RequestPart(value = "registerRequest") RegisterRequest registerRequest, 
@RequestPart(value = "attachment", required = false) MultipartFile file) throws ServiceException { 
    return memberV1Service.register(registerRequest, file); 
} 

我建議你應該檢查你的請求。而不是你的服務器端代碼。 這裏是我的測試預覽代碼(我在Chrome測試使用郵差)

POST /was/interface/member/v1/register.do HTTP/1.1 
    Host: localhost:8080 
    Cache-Control: no-cache 

    ----WebKitFormBoundaryE19zNvXGzXaLvS5C 
    Content-Disposition: form-data; name="registerRequest" 

    { -- some of my json format content} 
    ----WebKitFormBoundaryE19zNvXGzXaLvS5C 
    Content-Disposition: form-data; name="attachment"; filename="IMG_0089.JPG" 
    Content-Type: image/jpeg 


    ----WebKitFormBoundaryE19zNvXGzXaLvS5C 

的Content-Type中缺少request.This測試失敗,MissingServletRequestPartException原因所需要的請求部分「registerRequest」不存在。

您可以使用RESTClient或其他方式進行測試,並檢查Content-Type是否存在。