How can I have case insensitive URLS in Spring MVC with annotated mappings

I have annotated mappings working great through my spring mvc web app, however, they are case sensitive. I cannot find a way to make them case insensitive. (I'd love to make this happen within Spring MVC, rather than redirecting traffic somehow)


Solution 1:

Spring 4.2 will support case-insensitive path matching. You can configure it as follows:

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        AntPathMatcher matcher = new AntPathMatcher();
        matcher.setCaseSensitive(false);
        configurer.setPathMatcher(matcher);
    }
}

Solution 2:

According to this webpost you need to add both a HandlerMapping and a HandlerAdapter in Spring MVC. The Mapping maps the request to a corresponding controller, and the adapter is responsible to execute the request using the controller.

You therefore need to override the PathMatcher for both the mapper and adapter.

Ex (will make all @Controllers case-insensitive):

New Matcher:

public class CaseInsenseticePathMatcher extends AntPathMatcher {
    @Override
    protected boolean doMatch(String pattern, String path, boolean fullMatch, Map<String, String> uriTemplateVariables) {
        System.err.println(pattern + " -- " + path);
        return super.doMatch(pattern.toLowerCase(), path.toLowerCase(), fullMatch, uriTemplateVariables);
    }
}

applicationContext.xml:

<bean id="matcher" class="test.CaseInsenseticePathMatcher"/>

<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="pathMatcher" ref="matcher"/>
</bean>

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="pathMatcher" ref="matcher"/>
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"/>
    </property>
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
        </list>
    </property>
</bean>

<bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"/>

Added about the same that <mvc:annotation-driven> would do. (Thanks to David Parks for the link)

Solution 3:

In Spring 3.2+ / Spring Boot, you can now set up case insensitive URL matching using the simplified Java config.

First you need to create the CaseInsensitivePathMatcher.groovy or Java class:

import org.springframework.util.AntPathMatcher

class CaseInsensitivePathMatcher extends AntPathMatcher{

    @Override
    protected boolean doMatch(String pattern, String path, boolean fullMatch, Map<String, String> uriTemplateVariables) {
        super.doMatch(pattern.toLowerCase(), path.toLowerCase(), fullMatch, uriTemplateVariables)
    }
}

Next, to make this happen, you should have a class annotated with Springs @Configuration that extends the WebMvcConfigurerAdapter class as shown below (Note that my code is contained within .groovy classes, hence the 'return' keyword is not required in the example):

@Configuration
public class ApplicationConfig extends WebMvcConfigurerAdapter

Then add the following 2 methods to the class:

/**
 * Creates a patchMatcher bean that matches case insensitively
 * @return PathMatcher
 */
@Bean
public PathMatcher pathMatcher() {
    new CaseInsensitivePathMatcher()
}

/**
 * Overrides the configurePathMatch() method in WebMvcConfigurerAdapter
 * <br/>Allows us to set a custom path matcher, used by the MVC for @RequestMapping's
     * @param configurer
     */
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.pathMatcher = pathMatcher()
    }
}


That's it, you should now be all setup for case insensitive URL's with minimal configuration