SpringBoot get请求返回 错误码 406 Not Acceptable

本文详细介绍了在SpringBoot项目中,使用@RestController注解时,遇到以.txt为后缀的文件查询接口返回406错误的问题及解决方法。通过分析ContentNegotiatingViewResolver的工作原理,提出两种解决方案:一是避免使用.txt后缀,二是通过自定义WebMvcConfig类禁用后缀名协商。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景描述

今天需要写查询服务器上某一个文件是否存在,整个Controller注解为@RestController
代码大致如下

@ApiOperation(value = "查询文件是否存在")
    @RequestMapping(value = "/query/{filename:.+}", method = RequestMethod.GET)
    public JSONData query(@PathVariable String filename){
        String filePath= appProperties.getFilePath() + filename;
        boolean exist = false;
        File file = new File(filePath);
        if(file.exists()){
        	exist = true;
		}
		Map data = Maps.newHashMap();
		data.put("exist",exist);
        return JSONData.builder().msg(EnumResponseMsg.RESP_SUCCESS_0000.getMsg()).
              code(EnumResponseMsg.RESP_SUCCESS_0000.getCode()).data(data).success(true).build();
    }

PathVariable 填abcd.txt, URI为 /query/abcd.txt
利用swagger-ui 跑接口返回代码 406。

报错分析

注解@RestController意味着要把对象转换成json格式返回给请求端,有可能是缺少jackson相关的jar(例如jackson-core-asl-x.x.x.jar,jackson-mapper-asl-x.x.x.jar),springboot 的pom.xml应该是引用过这些jar的。况且其他的get也有返回内容,并没有出现406,问题应该不在这。
后面查到资料springmvc 以.html结尾的请求是不会返回JSON数据,很有可能以 .txt 结尾也是这个原因。
后查询资料证实:Spring Boot的MVC默认配置中使用的 ViewResolver 为 ContentNegotiatingViewResolver,该视图解析器的功能是根据要请求的文档类型,来查找不同的视图以返回对应格式的文档。请求的文档类型要可以从请求头中的Accept中获取,也可以通过URI后缀名得到,如/login.html即为请求HTML格式的文档,这两种方式分别对应着两种不同的Strategy(策略),默认为根据URI后缀名。

解决方法

初步定位是上述原因,那么怎么解决呢?
方法一、避免以.txt结尾的URL去访问,改变我们的@RequestMapping的value。我这边的情况不太适用。
方法二、继承WebMvcConfigurerAdapter 重写configureContentNegotiation方法禁用后缀方式进行内容协商

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
	@Override
	public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
		configurer.favorPathExtension(false);
	}
}

这种方式更适合我这边的场景,前后端分离,不需要后缀方式,干脆禁用掉。

### PHP调用第三方API返回406 Not Acceptable解决方案 当PHP应用程序向第三方服务发起HTTP请求并接收到`406 Not Acceptable`状态码时,这通常意味着客户端发送的内容类型或接受的内容类型不被服务器支持。为了处理这种情况,可以采取以下几个措施: #### 设置正确的Accept头 确保在发出请求之前设置了恰当的`Accept`头部字段来告知服务器期望接收的数据格式。对于大多数RESTful API而言,默认情况下应该设置为`application/json`。 ```php $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api.example.com/endpoint"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 添加Accept header指定可接受的内容类型 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Accept: application/json' ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($httpCode === 406) { echo "The server cannot produce a response matching the list of acceptable types."; } else { $result = json_decode($response, true); } curl_close($ch); ``` #### 验证Content-Type匹配 如果POST数据给API,则还需要确认提交的数据格式与所声明的`Content-Type`相一致。例如,在发送JSON编码后的字符串作为主体内容时,应当将此header设为`'Content-Type': 'application/json;charset=UTF-8'`. #### 处理不同版本的支持情况 有时特定资源可能仅存在于某些API版本中;因此建议查阅文档了解是否存在针对所需功能的不同版本路径,并尝试切换至兼容版次。 #### 检查自定义媒体类型的使用 部分高级别的Web APIs可能会采用带有参数的MIME类型(即所谓的“vendor-specific media type”),如`application/vnd.github.v3+json`. 如果目标平台确实提供了此类扩展形式,请按照官方说明调整相应的headers配置[^1].
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值