I want to map spring mvc controller to root (/**
) path (and not sub-folder such as "/something") while making exceptions with mvc:resources
(open to another method).
This should be the ABC of that framework but apparently is a very complicated stuff to ask of it.
My app-servlet.xml
has these obvious mapping exceptions:
<mvc:resources mapping="/favicon.ico" location="/favicon.ico" />
<mvc:resources mapping="/robots.txt" location="/robots.txt" />
And I have this controller:
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
@RequestMapping("/**")
public class MainController {
@RequestMapping(method = RequestMethod.GET)
public String service(final HttpServletRequest request) {
final String servlet_path = request.getServletPath();
System.out.println(String.format("%s %s", new Date().toString(), servlet_path));
return "test";
}
}
Now when I hit "/" or "/test" or "/test/page" I get output like:
Fri Aug 03 00:22:12 IDT 2012 /
Fri Aug 03 00:22:13 IDT 2012 /favicon.ico
.. see? service()
is being called for /favicon.ico
even when it's explicitly excluded!
Now I guess there's some "priority" to the @Controller
over the XML, still, how do I make the exclusion work?
A simple requirement - have the website on "/".
P.S This answer answers to a very similar question.
Another note: This question is not about tomcat context.
The issue here is that the underlying HandlerMapping registered with <mvc:resources
has a very low priority compared to the one registered with <mvc:annotation-driven/>
. If you requirement is to simply have something respond to "/" a better way probably will be to have a different @RequestMapping than /**
instead say have it as /home
and define something along these lines:
<mvc:view-controller path="/" view-name="home" />
If this will not work, the only other option will be to lower the priority of underlying handlerMapping of <mvc:resources
, which can be done by explicitly defining the HandlerMapping - a little complicated but can be done.
Updated
Here is a possible configuration:
Try with just this first:
<mvc:resources mapping="/favicon.ico" location="/favicon.ico" order="0"/>
<mvc:resources mapping="/robots.txt" location="/robots.txt" order="0"/>
If this alone does not work, change <mvc:annotation-driven/>
to something along these lines for Spring 3.1.x:
<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>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"></bean>
<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>
<bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter"></bean>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"></bean>
</list>
</property>
</bean>
<bean name="handlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping">
<property name="order" value="2"></property>
</bean>
I'd like to clarify that instead of rewriting the <mvc:annotation-driven/>
one can change the declaration order of the handler directives:
<mvc:resources mapping="/favicon.ico" location="/favicon.ico" order="0"/>
<mvc:resources mapping="/robots.txt" location="/robots.txt" order="0"/>
<mvc:annotation-driven/>