SpringMVC: Inconsistent mapping behavior depending on url extension

穿精又带淫゛_ 提交于 2019-11-29 06:49:46

It's not a bug, it's a feature...

As @axtavt and @rhinds have supposed, something is messing around which the content type. The browsers sends a correct Accept: application/json but spring ignores this and uses the extension of the url (aarrgh). From the docs:

16.16.4 Configuring Content Negotiation

You can configure how Spring MVC determines the requested media types from the client for
request mapping as well as for content negotiation purposes. The available options are to 
check the file extension in the request URI, the "Accept" header, a request parameter, as 
well as to fall back on a default content type. By default, file extension in the request 
URI is checked first and the "Accept" header is checked next.

The solution is quite simple as you can disable this "feature":

@Configuration
@EnableWebMvc
public class RestCommonsMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }

}

See also Spring does not ignore file extension for xml-config.

Related

I had required an extra step in my special case. I would like to add an extra information to @dirk-lachowski's great comment in case someone else needs. In my case I am importing an extension from WebMvcConfigurationSupport class

@Configuration
@EnableWebMvc
@Import({ SearchWebMvcConfigurationSupport.class })
public class SearchSpringConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(false);
    }
}

If you need to override requestMappingHandlerMapping method then you also have to add m.setUseSuffixPatternMatch(false);

@Configuration
public class SearchWebMvcConfigurationSupport extends WebMvcConfigurationSupport {
    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping m = super.requestMappingHandlerMapping();
        m.setAlwaysUseFullPath(true); // This makes your endpoints receive full path, including servlet mapping (you probably will not need this)
        m.setUseSuffixPatternMatch(false);
        return m;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!