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

场景描述

今天需要写查询服务器上某一个文件是否存在,整个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);
	}
}

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

你可能感兴趣的:(springboot)