17

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

I have Controller having multiple @RequestMapping annotations in it.

@Controller
public class SignUpController {

 @RequestMapping("signup")
 public String showSignUp() throws Exception {
    return "somejsp";
 }

 @RequestMapping("fullSignup")
 public String showFullSignUp() throws Exception {
    return "anotherjsp";
 }

 @RequestMapping("signup/createAccount")
 public String createAccount() throws Exception {
    return "anyjsp";
 }
}

How can I map these @RequestMapping to case insensitive. i.e. if I use "/fullsignup" or "/fullSignup" I should get "anotherjsp". But this is not happening right now. Only "/fullSignup" is working fine.

I've tried extending RequestMappingHandlerMapping but no success. I've also tried AntPathMatcher like the guy mentioned there is another question on this forum but its also not working for @RequestMapping annotation.

Debugging console enter image description here

Output console when server is up.

enter image description here

I've added two images which shows the problem. I've tried both the solutions mentioned below. The console says that it mapped lowercased URLS but when I request to access a method with lowercase url then it shows that the original map where the values are stored stilled contained MixCase URLS.

Community
  • 1
  • 1
Zahid Riaz
  • 2,879
  • 3
  • 27
  • 38
  • I'll refer you to http://stackoverflow.com/questions/4150039/how-can-i-have-case-insensitive-urls-in-spring-mvc-with-annotated-mappings – gtgaxiola Oct 02 '12 at 03:42
  • @gtgaxiola no this has nothing to do with RequestMapping. This works for Controller annotation only. I've tried this. – Zahid Riaz Oct 02 '12 at 04:11
  • Both answers are correct but with different approach. Whatever you choose. Depending upon urself. – Zahid Riaz Oct 05 '12 at 10:02
  • I know that its a duplicate but this have clear and detailed explanation. Which I was unable to find on that duplicate question. Thats why I offered bounty on this question. If the duplicated question was correct one why would I do that – Zahid Riaz Oct 06 '12 at 15:17

2 Answers2

12

One of the approaches in How can I have case insensitive URLS in Spring MVC with annotated mappings works perfectly. I just tried it with combinations of @RequestMapping at the level of controller and request methods and it has worked cleanly, I am just reproducing it here for Spring 3.1.2:

The CaseInsensitivePathMatcher:

import java.util.Map;

import org.springframework.util.AntPathMatcher;

public class CaseInsensitivePathMatcher extends AntPathMatcher {
    @Override
    protected boolean doMatch(String pattern, String path, boolean fullMatch, Map<String, String> uriTemplateVariables) {
        return super.doMatch(pattern.toLowerCase(), path.toLowerCase(), fullMatch, uriTemplateVariables);
    }
}

Registering this path matcher with Spring MVC, remove the <mvc:annotation-driven/> annotation, and replace with the following, configure appropriately:

<bean name="handlerAdapter" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="webBindingInitializer">
        <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
            <property name="conversionService" ref="conversionService"></property>
            <property name="validator">
                <bean class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
                    <property name="providerClass" value="org.hibernate.validator.HibernateValidator"></property>
                </bean>
            </property>
        </bean>
    </property>
    <property name="messageConverters">
        <list>
            <ref bean="byteArrayConverter"/>
            <ref bean="jaxbConverter"/>
            <ref bean="jsonConverter"/>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"></bean>
            <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter"></bean>
        </list>
    </property>
</bean>
<bean name="byteArrayConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
<bean name="jaxbConverter" class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
<bean name="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
<bean name="caseInsensitivePathMatcher" class="org.bk.lmt.web.spring.CaseInsensitivePathMatcher"/>
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
    <property name="pathMatcher" ref="caseInsensitivePathMatcher"></property>
</bean>

Or even more easily and cleanly using @Configuration:

@Configuration
@ComponentScan(basePackages="org.bk.webtestuuid")
public class WebConfiguration extends WebMvcConfigurationSupport{

    @Bean
    public PathMatcher pathMatcher(){
        return new CaseInsensitivePathMatcher();
    }
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = new RequestMappingHandlerMapping();
        handlerMapping.setOrder(0);
        handlerMapping.setInterceptors(getInterceptors());
        handlerMapping.setPathMatcher(pathMatcher());
        return handlerMapping;
    }
}
Community
  • 1
  • 1
Biju Kunjummen
  • 49,138
  • 14
  • 112
  • 125
4

The following simple solution should make @RequestMapping insensitive, whether it annotates a Controller or a method. Biju's solution should work too.

Create this custom HandlerMapping :

public CaseInsensitiveAnnotationHandlerMapping extends DefaultAnnotationHandlerMapping {

    @Override
    protected Object lookupHandler(String urlPath, HttpServletRequest request)
                    throws Exception {

        return super.lookupHandler(urlPath.toLowerCase(), request);
    }

    @Override
    protected void registerHandler(String urlPath, Object handler)
                    throws BeansException, IllegalStateException {

        super.registerHandler(urlPath.toLowerCase(), handler);
    }

}

And add this in your [servlet-name]-servlet.xml :

<bean class="yourpackage.CaseInsensitiveAnnotationHandlerMapping" />

Note: if you don't want two HandlerMapping in your app, you may want to remove <mvc:annotation-driven /> (it instantiates a DefaultAnnotationHandlerMapping).

Jerome Dalbert
  • 10,067
  • 6
  • 56
  • 64
  • can u please see my edited question – Zahid Riaz Oct 05 '12 at 04:45
  • 1
    @ZahidRiaz have you tried removing ? – Jerome Dalbert Oct 05 '12 at 08:51
  • I've tried But I got this error? javax.servlet.ServletException: No adapter for handler [net.hrms.web.controller.SignUpController@6f70829e]: Does your handler implement a supported interface like Controller? – Zahid Riaz Oct 05 '12 at 09:09
  • 1
    @ZahidRiaz When you remove ``, you must replace it by the usual beans it instantiates. See [this link (click here)](https://gist.github.com/861863) : just replace `DefaultAnnotationHandlerMapping` by `CaseInsensitiveAnnotationHandlerMapping` in the xml. – Jerome Dalbert Oct 05 '12 at 09:19
  • This will did the trick. +1 for different solution. Thanks man. You save the day – Zahid Riaz Oct 05 '12 at 10:01
  • @ZahidRiaz: Hi so where does the custom handler mapping go exactly? Do you put it in the the mycontroller.java file or a separate handlermapping.java file or somewhere else? – genxgeek Aug 02 '13 at 16:02
  • @JaJ Create a new java file and add the entry of that file like mentioned in answer. – Zahid Riaz Aug 03 '13 at 07:28
  • @ZahidRiaz: so it looks like DefaultAnnotationHandlerMapping is deprecated in spring 3.2.2. what is the alternative to this class? – genxgeek Aug 04 '13 at 01:27