我最近遇到了同样的问题并发现了问题。想在这里分享它,因为它会帮助别人。 @Patrick 解释的这种行为似乎是由于 Spring MVC 中基于 基于 URL(URL 后缀)的内容协商而发生的。
什么是内容协商?
在某些情况下,我们必须处理控制器返回的相同数据的多个表示(或视图)。确定要返回的数据格式称为内容协商。
内容协商如何运作?
通过 HTTP 发出请求时,可以通过设置 Accept 标头属性来指定您想要的响应类型。然而,浏览器实际上会发送非常混乱的Accept 标头,这使得依赖它们变得不切实际。因此 Spring 为内容协商提供了一些替代约定。
Spring Content Negotiation Alternatives - URL 后缀和/或 URL 参数
这些与Accept 标头一起使用。结果,
可以通过三种方式中的任何一种来请求内容类型。默认情况下,他们
按此顺序检查:
在问题中解释的上述案例中,您看到的是基于路径扩展的内容协商在起作用。 (.au)
来自ContentNegotiationConfigurer的哈瓦文档,
favorPathExtension
公共 ContentNegotiationConfigurer 偏爱路径扩展(布尔
喜欢路径扩展)
是否应该使用 URL 路径中的路径扩展来确定
请求的媒体类型。
默认设置为 true,在这种情况下请求 /hotels.pdf
将被解释为对“application/pdf”的请求,无论
“接受”标头。
解决方案 - 将喜爱路径扩展设置为 false
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(true).
parameterName("mediaType").
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.APPLICATION_JSON).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
}
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="parameterName" value="mediaType" />
<property name="ignoreAcceptHeader" value="true"/>
<property name="useJaf" value="false"/>
<property name="defaultContentType" value="application/json" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
</bean>
请注意,除了将喜爱路径扩展设置为 false 之外,上述配置还有一些其他更改。
更多详情请见here。
为了补全,我们得到的问题回复如下。
{
"timestamp": 1518691842254,
"status": 406,
"error": "Not Acceptable",
"exception": "org.springframework.web.HttpMediaTypeNotAcceptableException",
"message": "Not Acceptable",
"path": "/rest/token/something.au"
}