Spring MVC RequestMappingHandlerMapping happens twice when application starts

I recently converted my Spring 4 MVC web application from XML configuration to a java based configuration. After doing so, all of the controllers are mapped twice. I feel like it has to do with the component scans but I am not able to figure out why. I can post the old XML configuration setup if that will help. The application works fine, it just prints the controller mapping twice in the logs.

Here they are loaded to the root context

...
INFO  RequestMappingHandlerMapping - Mapped "{[/user/changePassword],methods=[POST]}" onto public org.springframework.web.servlet.ModelAndView com.rapidtest.mvc.controller.UserController.changePasswordSubmit(com.rapidtest.mvc.form.user.ChangePasswordFormBean,org.springframework.validation.BindingResult) throws java.lang.Exception
INFO  SimpleUrlHandlerMapping - Mapped URL path [/pub/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO  SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
INFO  RequestMappingHandlerAdapter - Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Thu Oct 22 16:16:24 MDT 2015]; root of context hierarchy

Here they are also loaded to the message dispatcher context

...
INFO  RequestMappingHandlerMapping - Mapped "{[/user/changePassword],methods=[POST]}" onto public org.springframework.web.servlet.ModelAndView com.rapidtest.mvc.controller.UserController.changePasswordSubmit(com.rapidtest.mvc.form.user.ChangePasswordFormBean,org.springframework.validation.BindingResult) throws java.lang.Exception
INFO  SimpleUrlHandlerMapping - Mapped URL path [/pub/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO  SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler]
INFO  RequestMappingHandlerAdapter - Looking for @ControllerAdvice: WebApplicationContext for namespace 'website-servlet': startup date [Thu Oct 22 16:16:28 MDT 2015]; parent: Root WebApplicationContext

Here is my web.xml

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

    <servlet>
        <servlet-name>website</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.rapidtest.config.mvc.MVCConfig</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>website</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
      <param-name>contextClass</param-name>
      <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
    </context-param>
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.rapidtest.config.spring</param-value>
    </context-param>
    <context-param>
        <param-name>contextInitializerClasses</param-name>
        <param-value>com.rapidtest.util.properties.ArchaiusPropertyInitializer</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    <filter>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.rapidtest.web.filter.EncodingFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>

    <error-page>
        <error-code>404</error-code>
        <location>/error/404</location>
    </error-page>

    <error-page>
        <location>/error/general</location>
    </error-page>

</web-app>

Here is my java MVC Configuration

package com.rapidtest.config.mvc;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
@ComponentScan("com.rapidtest.mvc.controller")
public class MVCConfig extends WebMvcConfigurationSupport {

    // <mvc:resources mapping="/pub/**" location="/pub/" />
    @Override
    public void addResourceHandlers(final ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pub/**").addResourceLocations("/pub/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    //  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    //      <property name="prefix">
    //          <value>/WEB-INF/jsp/</value>
    //      </property>
    //      <property name="suffix">
    //          <value>.jsp</value>
    //      </property>
    //  </bean>
    @Bean
    public ViewResolver configureViewResolver() {
        InternalResourceViewResolver viewResolve = new InternalResourceViewResolver();
        viewResolve.setPrefix("/WEB-INF/jsp/");
        viewResolve.setSuffix(".jsp");

        return viewResolve;
    }

    // <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
    @Bean(name = "multipartResolver")
    public CommonsMultipartResolver getMultipartResolver() {
        return new CommonsMultipartResolver();
    }

}

Here is my RootConfig. All of my other @Configuration classes are in the same package.

package com.rapidtest.config.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;

import com.rapidtest.util.properties.ArchaiusPropertyPlaceholderConfigurer;

@Configuration
//@ComponentScan(basePackages = {"com.rapidtest"}, useDefaultFilters=false, excludeFilters={
//        @ComponentScan.Filter(type=FilterType.ANNOTATION, value={Controller.class, ControllerAdvice.class})})
@ComponentScan(basePackages = {"com.rapidtest"} )
public class RootConfig {

    //<bean id="propertyConfigurer" class="com.rapidtest.util.properties.ArchaiusPropertyPlaceholderConfigurer" />
    @Bean(name = "propertyConfigurer")
    public static ArchaiusPropertyPlaceholderConfigurer getPropertyPlaceholder() {
        return new ArchaiusPropertyPlaceholderConfigurer();
    }
}

Answer

I was able to solve the problem by ignoring all @Configuration classes from the component scan.

@ComponentScan(basePackages = { "com.rapidtest.*" }, excludeFilters = {
    @ComponentScan.Filter(type = FilterType.ANNOTATION, value = { Configuration.class }) 
})

Leave a Reply

Your email address will not be published. Required fields are marked *