【问题标题】:File download using RESTful gives HTTP 406 Not Applicable Error使用 RESTful 下载文件会出现 HTTP 406 Not Applicable 错误
【发布时间】:2015-10-20 18:22:49
【问题描述】:

我正在尝试使用 RESTful 调用下载 Excel 文件。我认为这应该很简单,但我不断收到 HTTP 406 Not Applicable 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);
    }
});

我已经注释掉了我尝试并删除的行,因为它没有帮助。这可能是一个非常简单的配置更改,但我似乎无法弄清楚。

【问题讨论】:

  • 内容类型被声明了两次,一次在@RequestMapping 注释中的produces 值中,另一次在ResponseBuilder 中。尝试删除其中一个。
  • @ESala 删除一个没有帮助。尝试更改为ResponseBuilder builder = Response.ok(templateFile); 仍然得到相同的错误。

标签: java spring rest extjs download


【解决方案1】:

当您使用 @ResponseBody 注释请求映射返回类型时,Spring 将尝试使用 HttpMessageConverter 将对象转换为响应,正如它在 reference 页面上所说:

@ResponseBody 与@RequestBody 一样,Spring 将返回的对象转换为 使用 HttpMessageConverter 的响应正文。

您可以在此处查看可用转换器的列表:Message converters

您指定的application/vnd.ms-excel 似乎不受任何转换器支持。也许这就是你得到 406 的原因。

406 不可接受 请求的资源只能生成根据发送的 Accept headers 不可接受的内容 在请求中。

您的解决方案是删除@ResponseBody 注释并以其他方式处理文件下载

有关如何从 Spring 控制器下载文件的示例,请参见此处:

Downloading a file from Spring controllers

Returning a file from a controller in Spring

【讨论】:

  • application/octet-stream 也有同样的问题,它在你提到的消息转换器列表中。
【解决方案2】:

根据 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();
}

【讨论】:

    猜你喜欢
    • 2021-01-21
    • 1970-01-01
    • 2016-02-21
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 2018-06-24
    • 2011-04-28
    • 1970-01-01
    相关资源
    最近更新 更多