Spring不忽略文件扩展名
问题内容:
在我的Spring XML中,我有以下片段:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="useDefaultSuffixPattern" value="false"/>
</bean>
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="objectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
据我了解,这意味着春天应该 不是 当我有“ABC”映射寄存器“ABC *”和“ABC /”。
在我的一个控制器中,我有一个将图像写入响应的方法:
@RequestMapping(value="{path}", method=RequestMethod.GET, produces=MediaType.IMAGE_PNG_VALUE)
@ResponseBody
public void getPath(
@PathVariable String path,
HttpServletResponse res) {
...
}
当我请求类似“ abc”之类的东西时,这很好用,但是当我请求“ abc.com”时,它会在文本中抛出406错误:
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers."
当我请求“ abc.img”时,“ path”参数仅接收文本“ abc”;Spring省略了扩展名。
看来Spring没有正确忽略后缀模式。为什么是这样?
编辑 : 我翻译了Dirk的注释的Java配置,以下XML似乎可以解决此问题:
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
</bean>
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
<mvc:message-converters>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="objectMapper" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
我仍然不确定为什么原来的代码无法正常工作,但这已经解决了我的问题
问题答案:
当有请求发送到Spring调度程序时,控制器映射/匹配的一部分是将客户端上可接受的媒体类型与控制器上可生产的媒体类型进行匹配(因此,您可以使控制器只能通过其产生的媒体类型来区分)
。
坏消息是springmvc在其默认配置下,比请求中的任何accept标头更喜欢 扩展 请求的url。
在您的示例中,当您请求abc
扩展名不匹配时,其他有争议的协商策略将开始最终解决为正确的类型(通过accept
标头)。但是,如果您请求abc.com
spring会派生出application/octet- stream
与produces
控制器的不匹配的mime类型并生成406
(因为没有匹配的控制器)。
您可以在的spring-context-
support.jar中找到默认的mime匹配路径扩展org/springframework/mail/javamail/mime.types
(请参阅https://github.com/spring-
projects/spring-framework/blob/master/spring-context-support/src/ main /
resources / org / springframework / mail / javamail /
mime.types#L278
)。
您可以在调度程序配置中禁用此“功能”,以使spring不会使用路径扩展来解析mime类型:
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
</bean>