6
votes

I have web project with Spring and Spring security. My web.xml:

    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0" >
        <display-name>BillBoard
        </display-name>
        <session-config>
            <session-timeout>
                30
            </session-timeout>
        </session-config>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <listener>
            <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
        </listener>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:security-config.xml classpath:billboard-servlet.xml</param-value>
        </context-param>
        <servlet>
            <servlet-name>billboard</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:security-config.xml classpath:billboard-servlet.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>

        </servlet>
        <servlet-mapping>
            <servlet-name>billboard</servlet-name>
            <url-pattern>*.html</url-pattern>
        </servlet-mapping>
        <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>
        </filter-mapping>
    </web-app>

In server logs I see Spring context is loaded twice (spring bean initialization, database createtion...). At first time DispatcherServlet does it, and at the secont time ContextLoaderListener. How can I fix it?

In this tutorial I see that if contextParam is presented then servlet init-params are not required. But if I remove init params I have error: "org.apache.catalina.LifecycleException: org.apache.catalina.LifecycleException: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/billboard-servlet.xml]". Dispather servlet finds context-configuration in default location.

5

5 Answers

6
votes

You still need a context for your servlet:

Upon initialization of a DispatcherServlet, Spring MVC looks for a file named [servlet-name]-servlet.xml in the WEB-INF directory of your web application and creates the beans defined there, overriding the definitions of any beans defined with the same name in the global scope.

You don't need to load it as context-param in the ContextLoaderListener though.

Just leave the security-config.xml as context-param (it has to go there, as security is global per application), and billboard-servlet.xml as contextConfigLocation of your servlet and it should work.

3
votes

I had the same issue and the reason was:

<load-on-startup>1</load-on-startup

2
votes

These are two independent methods to do the same thing. Drop the ContextLoaderListener, for example.

1
votes

Since you have spring delegatingFilterProxy, if you drop contextLoaderLister you will get the below exception.

java.lang.IllegalStateException: No WebApplicationContext found: 
no   ContextLoaderListener registered?

So load security-config.xml via contextLoaderLister and billboard-servlet.xml via dispatcher servlet.

0
votes

When you configure the spring MVC framework configuration in the XML, you may configure it as bellow:

<!-- for Spring context loader -->
<servlet>
    <servlet-name>billboard</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:security-config.xml classpath:billboard-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>

</servlet>

this configuration will cause the IoC container initialize twice.

You should change the default servlet name[billboard] to others to solve this problem.

Because your dispatcher servlet is using the default context namespace [name of servlet]-servlet.xml (in the case billboard-servlet.xml) then Spring MVC will automatically load it.

For more details see: https://www.conqtech.com/blog/?p=85