Spring不会忽略文件扩展名

use*_*343 4 java spring uri spring-mvc http-status-code-406

在我的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>
Run Code Online (Sandbox Code Playgroud)

据我了解,这意味着春天应该登记"ABC*"和"ABC /"当我有"ABC"的映射.

在我的一个控制器中,我有一个将图像写入响应的方法:

@RequestMapping(value="{path}", method=RequestMethod.GET, produces=MediaType.IMAGE_PNG_VALUE)
@ResponseBody
public void getPath(
        @PathVariable String path,
        HttpServletResponse res) {

    ...
}
Run Code Online (Sandbox Code Playgroud)

当我请求像"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."
Run Code Online (Sandbox Code Playgroud)

当我请求"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>
Run Code Online (Sandbox Code Playgroud)

我仍然不确定为什么原来的代码不起作用,但这解决了我的问题

Dir*_*ski 13

当请求进入spring调度程序时,控制器映射/匹配的一部分是将客户端上接受的媒体类型与控制器端的可生成媒体类型相匹配(因此您可以拥有仅可通过其生成的媒体类型区分的控制器) .

坏消息是,在用SpringMVC默认配置有利于延长请求的URL在任何接受该请求头.

在您的示例中,当您请求abc时,扩展程序上没有匹配项,因此其他有争议的协商策略正在最终解析为正确的类型(通过accept标头).但是如果你请求abc.comspring将导出一个与你的控制器application/octet-stream不匹配的mime类型produces并生成一个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>
Run Code Online (Sandbox Code Playgroud)

如果您使用的是java配置,请查看我的相关问题/答案.

  • 完美的答案。但是不要忘记在注解驱动中指定自定义的Content Negotiation Manager -&gt; ''&lt;mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" /&gt;'' (2认同)