【发布时间】:2017-12-15 11:34:22
【问题描述】:
我有一个控制器,它的方法返回 text/csv。这适用于正常的成功案例,但如果抛出异常,并且我有 Accept: text/csv 的标头,我会收到 406 响应。例如:
@RequestMapping(value = "/foo", method = RequestMethod.GET, produces = "text/csv")
public String getCsv() {
throw new IllegalArgumentException();
}
这是一个完全普通的 Spring Boot 应用程序(Maven 项目,导入 spring-boot-starter-web-services),只包含具有上述方法的控制器。
我认为原因是框架正在将异常转换为 JSON 错误响应。如果我删除 produces 属性并发送 Accept: */* 我会得到异常的 JSON 表示。显然 JSON 不是 text/csv,因此是 406(不可接受)响应。
这是一个显示问题的 curl 请求/响应示例:
curl -v http://localhost:8080/foo -H 'accept: text/csv'
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /foo HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> accept: text/csv
>
< HTTP/1.1 406
< X-Application-Context: application
< Content-Length: 0
< Date: Sat, 16 Dec 2017 23:04:05 GMT
<
* Connection #0 to host localhost left intact
但是,有趣的是,如果我查看 Spring 应用程序中的 /trace 端点,我会看到一些不同的东西:
{
"timestamp": 1513465445542,
"info": {
"method": "GET",
"path": "/foo",
"headers": {
"request": {
"host": "localhost:8080",
"user-agent": "curl/7.47.0",
"accept": "text/csv"
},
"response": {
"X-Application-Context": "application",
"status": "500"
}
},
"timeTaken": "1"
}
}
所以,Spring 认为它返回 500,但当它卷曲时,它是 406。如果我从 PostMan 发送请求,我会看到完全相同的内容。
我不确定是什么导致了从 500 到 406 的变化。我认为它不是客户端,所以我最好的猜测是 Tomcat 正在这样做。有没有办法阻止这种情况发生?还是我错过了其他一些可能性?
【问题讨论】: