2015-10-20 106 views
1

我在嘗試使用RESTful調用下載Excel文件。我認爲它應該很簡單,但我一直在收到HTTP 406不適用Eror。這是我的控制器方法是什麼樣子:使用RESTful給文件下載HTTP 406不適用錯誤

@RequestMapping(value = "/gettemplate", method = RequestMethod.GET, produces = "application/vnd.ms-excel") 
@ResponseBody 
public Response getExcelTemplate() throws Exception { 
    File templateFile = new File("TestFile.xlsx"); 
    ResponseBuilder builder = Response.ok(templateFile,"application/vnd.ms-excel"); 
    builder.header("Content-Disposition", "attachment; filename=\"" + templateFile.getName() + "\""); 
    return builder.build(); 
} 

我試過設置請求頭接受application/vnd.ms-excel,我也用application/octet-stream代替vnd.ms-excel嘗試。在任何一種情況下,我都會收到一個帶有406錯誤消息的HTML響應。這裏是我的Ajax測試呼叫的樣子:

Ext.Ajax.request({ 
    url: 'myservice/gettemplate', 
    //dataType: 'application/vnd.ms-excel', 
    headers: { 
     'Accept': 'application/vnd.ms-excel, text/plain, */*' 
     //'Content-Type': 'application/vnd.ms-excel' 
    }, 
    success: function (response, options) { 
     alert(1); 
    }, 
    failure: function (response, options) { 
     alert(2); 
    } 
}); 

我註釋掉了,我試過和刪除,因爲它並沒有幫助的線條。這可能是一個非常簡單的配置更改,但我似乎無法弄清楚。

+0

內容類型被聲明兩次,一次在@RequestMapping註釋中的「產生式」值和另一個在ResponseBuilder上。嘗試刪除其中一個。 – ESala

+0

@ESala刪除一個沒有幫助。嘗試改變爲'ResponseBuilder builder = Response.ok(templateFile);'仍然得到相同的錯誤。 –

回答

0

有點基於埃薩拉的答案,我嘗試了一些東西。最後通過將標題和內容類型設置爲HttpServletResponse來解決問題。這是爲我工作的代碼。這在IE和Firefox中都可以正常工作,只需一個簡單的錨標記,甚至不需要Ajax調用。希望它可以幫助別人。

@RequestMapping(value ="/gettemplate", method = RequestMethod.GET) 
@ResponseBody 
public void getExcelTemplate(HttpServletRequest request, HttpServletResponse response) throws Exception{ 
    response.setContentType("application/vnd.ms-excel"); 
    response.setHeader("content-disposition", "attachment; filename=TestFile.xlsx"); 

    InputStream fis = getClass().getClassLoader().getResourceAsStream("templates/TestFile.xlsx"); 
    int x = fis.available(); 
    byte byteArray[] = new byte[x]; 
    logger.info(" File size :"+byteArray.length); 
    fis.read(byteArray); 

    response.getOutputStream().write(byteArray); 
    response.flushBuffer(); 
    fis.close(); 
} 
2

當你標註的請求映射返回類型與@ResponseBody,春天將嘗試使用HttpMessageConverter對象轉換成響應,因爲它說的reference頁:

@ResponseBody與@ RequestBody,Spring通過使用HttpMessageConverter將返回的對象轉換爲 響應正文。

這裏你可以看到可用的轉換器的列表:Message converters

它看起來像您指定的application/vnd.ms-excel不受任何轉換器的支持。也許這就是爲什麼你得到一個406

406不可接受 所請求的資源只能生成內容根據接受頭不能接受的請求發送 。

你的情況的解決方法是刪除@ResponseBody註釋和處理文件下載以另一種方式

看到這裏如何從一個Spring控制器下載文件的例子:

Downloading a file from Spring controllers

Returning a file from a controller in Spring

+1

我也有'application/octet-stream'的問題,它在你提到的消息轉換器列表中。 –