Spring MVC @PathVariable with dot (.) is getting truncated

后端 未结 17 1309
被撕碎了的回忆
被撕碎了的回忆 2020-11-22 06:00

This is continuation of question Spring MVC @PathVariable getting truncated

Spring forum states that it has fixed(3.2 version) as part of ContentNegotiationManager.

相关标签:
17条回答
  • 2020-11-22 06:30

    Here's an approach that relies purely on java configuration:

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
    import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
    
    @Configuration
    public class MvcConfig extends WebMvcConfigurationSupport{
    
        @Bean
        public RequestMappingHandlerMapping requestMappingHandlerMapping() {
            RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();
            handlerMapping.setUseSuffixPatternMatch(false);
            handlerMapping.setUseTrailingSlashMatch(false);
            return handlerMapping;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:30

    Finally I found solution in Spring Docs:

    To completely disable the use of file extensions, you must set both of the following:

     useSuffixPatternMatching(false), see PathMatchConfigurer
    
     favorPathExtension(false), see ContentNegotiationConfigurer
    

    Adding this to my WebMvcConfigurerAdapter implementation solved the problem:

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }
    
    @Override
    public void configurePathMatch(PathMatchConfigurer matcher) {
        matcher.setUseSuffixPatternMatch(false);
    }
    
    0 讨论(0)
  • 2020-11-22 06:36

    As of Spring 5.2.4 (Spring Boot v2.2.6.RELEASE) PathMatchConfigurer.setUseSuffixPatternMatch and ContentNegotiationConfigurer.favorPathExtension have been deprecated ( https://spring.io/blog/2020/03/24/spring-framework-5-2-5-available-now and https://github.com/spring-projects/spring-framework/issues/24179).

    The real problem is that the client requests a specific media type (like .com) and Spring added all those media types by default. In most cases your REST controller will only produce JSON so it will not support the requested output format (.com). To overcome this issue you should be all good by updating your rest controller (or specific method) to support the 'ouput' format (@RequestMapping(produces = MediaType.ALL_VALUE)) and of course allow characters like a dot ({username:.+}).

    Example:

    @RequestMapping(value = USERNAME, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public class UsernameAPI {
    
        private final UsernameService service;
    
        @GetMapping(value = "/{username:.+}", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.ALL_VALUE)
        public ResponseEntity isUsernameAlreadyInUse(@PathVariable(value = "username") @Valid @Size(max = 255) String username) {
            log.debug("Check if username already exists");
            if (service.doesUsernameExist(username)) {
                return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
            }
            return ResponseEntity.notFound().build();
        }
    }
    

    Spring 5.3 and above will only match registered suffixes (media types).

    0 讨论(0)
  • 2020-11-22 06:38

    As far as i know this issue appears only for the pathvariable at the end of the requestmapping.

    We were able to solve that by defining the regex addon in the requestmapping.

     /somepath/{variable:.+}
    
    0 讨论(0)
  • 2020-11-22 06:41

    Update for Spring 4: since 4.0.1 you can use PathMatchConfigurer (via your WebMvcConfigurer), e.g.

    @Configuration
    protected static class AllResources extends WebMvcConfigurerAdapter {
    
        @Override
        public void configurePathMatch(PathMatchConfigurer matcher) {
            matcher.setUseRegisteredSuffixPatternMatch(true);
        }
    
    }
    
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
       @Override
       public void configurePathMatch(PathMatchConfigurer configurer) {
           configurer.setUseSuffixPatternMatch(false);
       }
    }
    

    In xml, it would be (https://jira.spring.io/browse/SPR-10163):

    <mvc:annotation-driven>
        [...]
        <mvc:path-matching registered-suffixes-only="true"/>
    </mvc:annotation-driven>
    
    0 讨论(0)
  • 2020-11-22 06:41

    The complete solution including email addresses in path names for spring 4.2 is

    <bean id="contentNegotiationManager"
        class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
        <property name="favorPathExtension" value="false" />
        <property name="favorParameter" value="true" />
        <property name="mediaTypes">
            <value>
                json=application/json
                xml=application/xml
            </value>
        </property>
    </bean>
    <mvc:annotation-driven
        content-negotiation-manager="contentNegotiationManager">
        <mvc:path-matching suffix-pattern="false" registered-suffixes-only="true" />
    </mvc:annotation-driven>
    

    Add this to the application-xml

    0 讨论(0)
提交回复
热议问题