2014-05-10 42 views
3

在我的春節,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」,「路徑」參數僅接收文本「ABC」; Spring省略了擴展。

看來Spring並沒有正確地忽略後綴模式。爲什麼是這樣?

編輯我翻譯了德克的評論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> 

我仍然不知道爲什麼原來的代碼我是不起作用,但是這已經解決了我的問題

+1

爲了記錄,我也試過使用@RequestMapping(value =「{path:。+}」),但沒有運氣 – user2221343

+0

也許你被同樣的問題困擾了。看看這個問題:http://stackoverflow.com/q/22329393/1686330 –

+0

是的,這似乎是相同的問題!我使用了這個問題的等價XML,並且能夠解決我的問題。如果你想把它作爲答案發布,我會很樂意接受它! – user2221343

回答

11

當請求進入彈簧調度程序時,控制器映射/匹配的一部分將客戶端上接受的媒體類型與可生成媒體類型控制器方面(因此您可以讓控制器僅通過其生產的介質類型進行區分)。

壞消息是springmvc在其默認配置中偏好請求中的任何接受標頭上請求的url的擴展

在您的示例中,當您請求abc時,擴展名上沒有匹配項,所以其他競爭對手的談判策略正在踢中,最終解析爲正確類型(通過accept標題)。但是如果你要求abc.com彈簧會產生一個MIME類型的application/octet-stream,它與你的控制器的produces不匹配,併產生一個406(因爲沒有匹配的控制器)。

您可以在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-context-support.jar中找到路徑擴展的默認mime匹配。

你可以在你的調度配置禁用此「功能」,所以春天就不會使用路徑擴展,以便解決MIME類型:

<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean"> 
    <property name="favorPathExtension" value="false" /> 
</bean> 

如果您使用的是Java的配置看看我的related question/answer

+1

完美的答案。但別忘了在註釋驅動中指定自定義內容協商管理器 - >'''' – Dani