Question

I am facing some difficulties when trying to create a certain url for @RequestMapping in a spring controller. First of all, because of the framework the project uses, there is a controller method mapped to the following url: "/{pageLabelOrId}"

Second, I have another controller method mapped to "/{pageName}.html". This works fine, meaning that if I try to access from browser "www.applicationUrl/something.html" this url if captured by the second method as is intended.

Now here is my problem. I must handle a somehow different but also similar url in a distinct method as follows: "/something-{parameter1}_{parameter2}_{parameter3}" Trying to access "www.applicationUrl/something-1_2_3" will trigger the first controller: "/{pageLabelOrId}" instead of the desired one.

Handling this kind of url("/something-1_2_3") is a requirement and I cannot change it to something like "/something/{param1}/{param2}/{param3}" which I am sure it will work.

I have observed however, that writing a controller method mapped to "/something-{param}" will work and will capture my three parameters in one PathVariable(like "1_2_3") that I can parse afterwards by "_".

Does anyone have any idea of why does spring has this behavior and if I can somehow make it to work using three different path variables?

Was it helpful?

Solution

Spring 3.1+ uses a RequestMappingHandlerMapping to create RequestMappingInfo objects which map your controller handler methods to their corresponding @RequestMapping paths. When the DispatcherServlet receives a request, it uses the RequestMappingHandlerMapping again to determine which handler method should be used.

The way it is currently implemented, it finds all the registered RequestMappingInfo objects that match the request and then sorts them based on a number of rules, basically those defined in AntPathMatcher and AntPatternComparator.

You'll have to configure your RequestMappingHandlerMapping bean to use a custom PathMatcher with your own rules for comparing.

How you do this depends on how you are doing your configuration. If you use a @Configuration class, you can do

@Configuration
public class WebConfig extends WebMvcConfigurationSupport {

    ...

    @Override
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping mapping = super.requestMappingHandlerMapping();
        mapping.setPathMatcher(pathMatcher()); // some PathMatcher bean
        return mapping;
    }

    ...
}

The RequestMappingInfo objects created by this RequestMappingHandlerMapping will internally use this PathMatcher. They will be sorted based on its Comparator.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top