2015-10-20 56 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'的问题,它在你提到的消息转换器列表中。 –