Spring-路径变量在点-注释后截断
问题内容:
我试图建立一个REST端点,该端点允许按用户的电子邮件地址查询该用户。电子邮件地址是路径的最后一部分,因此Spring将其foo@example.com
视为值foo@example
并截断了扩展名.com
。
我在这里发现了一个类似的问题,带有点(。)的Spring MVC@PathVariable被截断了。
但是,我有一个使用AbstractAnnotationConfigDispatcherServletInitializer
和的基于注释的配置WebMvcConfigurerAdapter
。由于我没有xml配置,因此该解决方案不适用于我:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="useDefaultSuffixPattern" value="false" />
</bean>
我也尝试过使用正则表达式的解决方案,但也没有用。
@RequestMapping(value = "user/by-email/{email:.+}")
有谁知道如何在没有xml的情况下关闭后缀模式截断?
问题答案:
URI末尾的path变量中的点引起两个意外行为(对于大多数用户而言,这是意外的,除了熟悉大量Spring配置属性的用户外)。
第一个( 可以
使用{email:.+}
正则表达式修复)是默认的Spring配置匹配所有路径扩展。因此,为建立映射/api/{file}
将意味着Spring将调用映射/api/myfile.html
到String参数myfile
。当你想这是非常有用的/api/myfile.html
,/api/myfile.md
,/api/myfile.txt
和其他人都指向相同的资源。但是,我们可以在全球范围内关闭此行为,
而 不必在每个端点上都使用正则表达式破解。
第二个问题与第一个有关,并已通过@masstroy正确解决。当/api/myfile.*
指向myfile
资源,春天假定路径扩展(.html
,.txt
等)表示的资源应该与特定的格式返回。在某些情况下,此行为也可能非常有用。但是通常,这意味着方法映射返回的对象无法转换为这种格式,Spring会抛出HttpMediaTypeNotAcceptableException
。
我们可以使用以下命令关闭两者(假设使用Spring Boot):
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
// turn off all suffix pattern matching
configurer.setUseSuffixPatternMatch(false);
// OR
// turn on suffix pattern matching ONLY for suffixes
// you explicitly register using
// configureContentNegotiation(...)
configurer.setUseRegisteredSuffixPatternMatch(true);
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false);
}
}
有关内容协商的更多信息。