If I create spring context by dispatcher servlet, I got an error inDelegatingFilterProxy
filter:
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:251)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.logging.log4j.core.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:66)
If I create spring context by ContextLoaderListener
I just have 404
error beacuse of no servlet
If I create spring context by both servlet & listener I have duplicated context, so all beans are duplicated, including controllers with request mappings, double-executing @Scheduled
methods etc.
How to create advanced spring application (including lot of filters etc.) without duplicating context?
My web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>MyWebApplication</display-name>
<servlet>
<servlet-name>springDispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring.xml
</param-value>
</context-param>
<!-- UTF-8 -->
<filter>
<filter-name>encoding-filter</filter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding-filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring Security -->
<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>
if you use spring related servlet filters and also use mvc controllers, then you need both:
(See ContextLoaderListener or not?)
Both create their own servlet context. The ContextLoaderListener create the parent-context (sometimes called the inner-context). And the DispatcherServlet create a child-context (of the parent context) (sometimes called the outer-context). The beans of the child-context can access the beans of the parent-context, but not the other way around.
In a not too simple web application you need both contexts, because the there are many servlet filters that requires an already created spring context. On the other hand, all the controller stuff needs a ServletContext, and this is only created by the Dispatcher Servlet.
Another point is, that you should not have every bean created twice (sometimes this is no problem, other times it is). So you need to have two spring configurations, one for the inner context, one for the other context. And you need to decide for every bean whether it belongs to the inner or to the outer context.
The rule of thumb is: put every thing in the inner context, except that stuff that requires a Servlet context or is heavily tied to the Web-frontend, like MVC-Controllers, Tiles configuration, ....
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With