user1717150
user1717150

Reputation:

Spring MVC and RequestMapping with filter

I am having a problem with url mappings and thought somebody might help me :-)

My Spring MVC application has a dispatcherServler's mapping as follows:

<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Then I have a controller servlet with a method annotated like this:

MyServlet {
....myMethod    
@RequestMapping(value = "/qwert/request", method = RequestMethod.POST)

To conclude I have a DelegatingFilterProxy with a mapping:

<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/qwert/request</url-pattern>
</filter-mapping>

whose target is to intercept all requests directed to the aforementioned MyServlet's method.

The application is working fine for the typical request localhost:port/MyApp/qwert/request which means that the filter is intercepting requests and doing its business.

The problems is that a request like this localhost:port/MyApp/qwert/request.do is getting directly into the Servlet (MyServlet) method without passing through the Filter. My @RequestMapping is not /qwert/request.do, how can the request end up arriving in the servlet?

Does anyone have any idea how to solve this without changing my dispatcherServlet mapping to something like *.do and making other changes accordingly.

I would like my application to serve requests under localhost:port/MyApp/qwert/request and not localhost:port/MyApp/qwert/request.whatever and I cannot change the filter mapping to /* since there are other methods that do not require the filter intervention.

Thanks

Update 1:

Yes, I tried to introduce a filter's url-pattern like /qwert/request.* but in that case the filter does not intercept any request. Neither localhost:port/MyApp/qwert/request nor localhost:port/MyApp/qwert/request.whatever (being the first one the one normal callers should be using)

Solution

At the end I found what the problem was, @Jhonathan pointed me in the right direction

I had to define a RequestMappingHandlerMapping instead of a DefaultAnnotationHandlerMapping

@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
    RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();      
    // no dot like names will be matched
    mapping.setUseSuffixPatternMatch(false);
    // no trailing slash will be matched
    mapping.setUseTrailingSlashMatch(false);
    return mapping;
}

That did the trick and I can now see internally that the pattern does not mach "wrong" requests like the ones I mentioned at the beginning.

Thank you all

Upvotes: 3

Views: 5083

Answers (1)

Jhonathan
Jhonathan

Reputation: 1601

First Question

My @RequestMapping is not /qwert/request.do, how can the request end up arriving in the servlet?

Spring by default take

/qwert/request.do 
/qwert/request.whatever
/qwert/request.*

like

/qwert/request 

therefore your @RequestMapping(value = "/qwert/request", method = RequestMethod.POST)take request. Change in your DefaultAnnotationHandlerMapping for change this default option:

 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
     <property name="useDefaultSuffixPattern" value="false" />
 </bean>

From Spring Source:

setUseDefaultSuffixPattern

public void setUseDefaultSuffixPattern(boolean useDefaultSuffixPattern)

Set whether to register paths using the default suffix pattern as well: i.e. whether "/users" should be registered as "/users." and "/users/" too. Default is "true". Turn this convention off if you intend to interpret your @RequestMapping paths strictly. Note that paths which include a ".xxx" suffix or end with "/" already will not be transformed using the default suffix pattern in any case.*

Upvotes: 0

Related Questions