Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put default-servlet-handler in Spring MVC configuration

In my web.xml, the default servlet mapping, i.e. /, is mapped to Spring dispatcher. In my Spring dispatcher configuration, I have DefaultAnnotationHandlerMapping, ControllerClassNameHandlerMapping and AnnotationMethodHandlerAdapter which allows me to map url to controllers either by its class name or its @Requestmapping annotation. However, there are some static resources under the web root which I also want spring dispatcher to serve using default servlet. According to Spring documentation, this can be done using <mvc:default-servlet-handler/> tag.

In the configuration below, there are 4 candidate locations that I marked which are possible to insert this tag. Inserting the tag in different location causes the dispatcher to behave differently as following :

Case 1 : If I insert it at location 1, the dispatcher will no longer be able to handle mapping by the @RequestMapping and controller class name but it will be serving the static content normally.

Cas 2, 3 : It will be able to handle mapping by the @RequestMapping and controller class name as well as serving the static content if other mapping cannot be done successfully.

Case 4 : It will not be able to serve the static contents. Removal Note : This was a bug when implementing a controller which has a method mapped to /** but does not have explicit request mapping on the controller class name.

Therefore, Case 2 and 3 are desirable .According to Spring documentation, this tag configures a handler which precedence order is given to lowest so why the position matters? and Which is the best position to put this tag?

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <context:annotation-config/>
    <context:component-scan base-package="webapp.controller"/>
    <!-- Location 1 -->

    <!-- Enable annotation-based controllers using @Controller annotations -->
    <bean id="annotationUrlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>

    <!-- Location 2 -->
    <bean id="controllerClassNameHandlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>

    <!-- Location 3 -->
    <bean id="annotationMethodHandlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

    <!-- Location 4 -->
    <mvc:default-servlet-handler/>

    <!-- All views are JSPs loaded from /WEB-INF/jsp -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
like image 413
gigadot Avatar asked Jan 07 '11 09:01

gigadot


People also ask

Which is the default handler mapping used by DispatcherServlet?

"By default the DispatcherServlet uses the BeanNameUrlHandlerMapping to map the incoming request. The BeanNameUrlHandlerMapping uses the bean name as the URL pattern. Since BeanNameUrlHandlerMapping is used by default, you need not do any seperate configuration for this."

What is Spring MVC servlet Path?

The servlet path represents the path of the main DispatcherServlet. The DispatcherServlet is an actual Servlet, and it inherits from HttpSerlvet base class. The default value is similar to the context path, i.e. (“/”): spring.mvc.servlet.path=/

Do we need to configure dispatcher servlet in Spring MVC?

form will be handled by the 'example' DispatcherServlet . This is only the first step in setting up Spring Web MVC... the various beans used by the Spring Web MVC framework (over and above the DispatcherServlet itself) now need to be configured.

What is default controller in Spring MVC?

The default handler is based on the @Controller and @RequestMapping annotations, offering a wide range of flexible handling methods. With the introduction of Spring 3.0, the @Controller mechanism also allows you to create RESTful Web sites and applications, through the @PathVariable annotation and other features.


2 Answers

By default, Spring sets the value of the order of HandlerMapping to Integer.MAX_VALUE which gives the lowest precedence order. When the dispatcher configuration is loaded for the first time, DispatcherServlet will use this values to sort the list of HandlerMapping's.

If the explicit value of order is not set, then all handler mapping object will have the same order of Integer.MAX_VALUE. Thus, after the sorting, the order of the handler mappings will remain the same as the order of the beans definitions. [this sounds like a bug in the implementation of dispatcher]

Therefore, if the order values of handler mappings are explicitly set, it is safe to put <mvc:default-servlet-handler/> tag anywhere in the bean definition.

Here is example :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
    <context:annotation-config/>
    <context:component-scan base-package="webapp.controller"/>

    <mvc:default-servlet-handler />

    <!-- Enable annotation-based controllers using @Controller annotations -->
    <bean id="annotationUrlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="order" value="0" />
    </bean>

    <bean id="controllerClassNameHandlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
        <property name="order" value="1" />
    </bean>

    <bean id="annotationMethodHandlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

    <!-- All views are JSPs loaded from /WEB-INF/jsp -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>
like image 150
gigadot Avatar answered Nov 15 '22 16:11

gigadot


I think this is down to poor wording in the documentation.

It configures a DefaultServletHttpRequestHandler with a URL mapping (given a lowest precedence order) of "/**"

I think this means you should give it a lower precedence order, and not that Spring will do this automatically.

I don't understand why putting it at location 4 doesn't work, though, I see no difference between location 4 and location 3 - the handler adapter should not interfere with the mapping precedence.

like image 26
skaffman Avatar answered Nov 15 '22 15:11

skaffman