No WebApplicationContext found: no ContextLoaderListener registered


修改前運行報錯:No WebApplicationContext found: no ContextLoaderListener registered? 

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  <filter>
      <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
<!--   配置shiro 過濾器 -->
  <filter>
      <filter-name>shiroFilter</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      <init-param>
          <param-name>targetFilterLifecycle</param-name>
          <param-value>true</param-value>
      </init-param>
      <init-param>
          <param-name>targetBeanName</param-name>
          <param-value>shiroFilter</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>shiroFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
<!--   配置springMVC核心控制器 -->
  <servlet>
      <servlet-name>DispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring_config.xml</param-value> </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>DispatcherServlet</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>

<welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <!-- 配置錯誤頁面 --> <error-page> <error-code>404</error-code> <location>/WEB-INF/jsp/common/error.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/jsp/common/error.jsp</location> </error-page> <error-page> <error-code>503</error-code> <location>/WEB-INF/jsp/common/error.jsp</location> </error-page> <error-page> <error-code>400</error-code> <location>/WEB-INF/jsp/common/error.jsp</location> </error-page> </web-app>

修改后:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>web</display-name>  
  <filter>
      <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
<!--   配置shiro 過濾器 -->
  <filter>
      <filter-name>shiroFilter</filter-name>
      <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
      <init-param>
          <param-name>targetFilterLifecycle</param-name>
          <param-value>true</param-value>
      </init-param>
      <init-param>
          <param-name>targetBeanName</param-name>
          <param-value>shiroFilter</param-value>
      </init-param>
  </filter>
  <filter-mapping>
      <filter-name>shiroFilter</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring_config.xml</param-value> </context-param>
  
<!--   配置springMVC核心控制器 -->
  <servlet>
      <servlet-name>DispatcherServlet</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring_mvc.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>DispatcherServlet</servlet-name>
      <url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <welcome-file-list>
      <welcome-file>login.jsp</welcome-file>
  </welcome-file-list>
       
  <!-- 配置錯誤頁面 -->
  <error-page>
      <error-code>404</error-code>
      <location>/WEB-INF/jsp/common/error.jsp</location>
  </error-page>
  <error-page>
      <error-code>500</error-code>
      <location>/WEB-INF/jsp/common/error.jsp</location>
  </error-page>
  <error-page>
      <error-code>503</error-code>
      <location>/WEB-INF/jsp/common/error.jsp</location>
  </error-page>
  <error-page>
      <error-code>400</error-code>
      <location>/WEB-INF/jsp/common/error.jsp</location>
  </error-page>
</web-app>

原因分析:

<filter>  
        <filter-name>shiroFilter</filter-name>  
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
        <init-param>  
            <param-name>targetFilterLifecycle</param-name>  
            <param-value>true</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>shiroFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
        <dispatcher>REQUEST</dispatcher>  
        <dispatcher>FORWARD</dispatcher>  
    </filter-mapping> 

  項目加載的shiro過濾器的功能需要依賴ContextLoaderListener所加載的apring_config.xml文件生成的applicationContext即Spring的上下文,而之前DispatcherServlet所加載的spring_mvc.xml文件生成的applicationContext為Spring mvc的上下文,shiro過濾器無法加載,所以得依靠監聽器加載public的applicationContext。

三個context之間的的關系:

  1. 對於一個web應用,web容器加載一個全局context(即servletContext)供其使用,為后面的spring IoC容器提供依賴。
  2. 在web.xml中提供的ContextLoaderListener監聽器,web容器啟動時會觸發容器初始化事件,ContextLoaderListener會監聽這個事件,初始化一個根上下文即WebApplicationContext,實現類為XmlWebApplicationContext。這個就是Spring的IoC容器,spring將其以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE為key存儲在servletContext中
  3. DispatcherServlet在初始化會建立自己的IoC容器用以持有Spring mvc相關的bean,它在建立的時候會通過WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE先從servletContext中獲取根上下文作為自己上下文的父上下文,它的實現類也是XmlWebApplicationContext,在建立之后會以和自己servlet-name便簽有關的名稱存儲在servletContext中,這樣每個servlet就擁有自己獨立的bean及根上下文共享的bean

  但是這樣會導致重復加載配置文件,DispatcherServlet、ContextLoaderListener會分別加載一次,解決方法是把配置文件拆分成2個,一個Spring mvc的配置文件,一個Spring的配置文件,DispatcherServlet加載Spring mvc的配置文件,ContextLoaderListener加載Spring的配置文件 。

Spring mvc在使用上下文的時候會使用DispatcherServlet加載的applicationContext,也會使用的contextLoaderListener加載的applicationContext。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM