我正在尝试使用RESTful调用下载Excel文件。我认为它应该很简单,但我一直得到HTTP 406不适用Eror。这就是我的控制器方法:
@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 :(得分:2)
当您使用@ResponseBody
注释请求映射返回类型时,Spring将尝试使用HttpMessageConverter
将对象转换为响应,如reference页面上所述:
@ResponseBody 与@RequestBody一样,Spring将返回的对象转换为 使用HttpMessageConverter响应正文。
您可以在此处查看可用转换器列表:Message converters
看起来任何转换器都不支持您指定的application/vnd.ms-excel
。也许这就是为什么你得到406。
406不可接受 请求的资源只能根据发送的Accept标头生成不可接受的内容 在请求中。
您的解决方案是删除@ResponseBody
注释,以其他方式处理文件下载。
有关如何从Spring控制器下载文件的示例,请参阅此处:
答案 1 :(得分:1)
根据ESala的回答,我做了一些尝试。最后通过将标题和内容类型设置为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();
}