Spring - 点 - 注释后的路径变量截断

mas*_*roy 11 java rest spring spring-mvc spring-annotations

我正在尝试设置一个REST端点,允许通过他们的电子邮件地址查询用户.电子邮件地址是路径的最后一部分,因此Spring将其foo@example.com视为值foo@example并截断扩展名.com.

我在这里发现了一个类似的问题Spring MVC @PathVariable with dot(.)被截断 但是,我有一个基于注释的配置使用AbstractAnnotationConfigDispatcherServletInitializerWebMvcConfigurerAdapter.由于我没有xml配置,这个解决方案对我不起作用:

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="useDefaultSuffixPattern" value="false" />
</bean>
Run Code Online (Sandbox Code Playgroud)

我也试过这个使用正则表达式的解决方案,但它也没有用.

@RequestMapping(value = "user/by-email/{email:.+}")
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何在没有xml的情况下关闭后缀模式截断?

bkj*_*vbx 19

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

有关内容协商的更多信息.


小智 14

您必须在名称之后的路径变量末尾添加尾部斜杠

 @RequestMapping(value ="/test/{name}/")
Run Code Online (Sandbox Code Playgroud)

请求喜欢

HTTP://本地主机:8080/utooa/service/api/admin/test/Takeoff.Java@gmail.com/


mas*_*roy 7

我已经使用ContentNegotiationConfigurer本文中的bean 找到了解决方案:http://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc

我在WebConfig类中添加了以下配置:

@EnableWebMvc
@Configuration
@ComponentScan(basePackageClasses = { RestAPIConfig.class })
public class WebConfig extends WebMvcConfigurerAdapter {    
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
        configurer.defaultContentType(MediaType.APPLICATION_JSON);
    }
}
Run Code Online (Sandbox Code Playgroud)

通过设置.favorPathExtension(false),Spring将不再使用文件扩展名来覆盖请求的接受mediaType.该方法的Javadoc读取Indicate whether the extension of the request path should be used to determine the requested media type with the highest priority.

然后我使用正则表达式设置我的@RequestMapping

@RequestMapping(value = "/user/by-email/{email:.+}")
Run Code Online (Sandbox Code Playgroud)