关于IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]的解决

来源:互联网 发布:手机壁纸diy软件 编辑:程序博客网 时间:2024/05/23 02:00

        最近学了Maven,并尝试将以前的项目(springmvc)重构成Maven项目,Maven项目推荐各种资源文件都放在src/Java/resources目录下,所以我自然把spring的配置文件(包括spring-mvc,spring-mybatis等配置都写在一个文件中)applicationContext.xml文件也放在了resources目录下,重构结束后,启动Tomcat报错:

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:343)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:540)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:454)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4717)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5179)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:596)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1805)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:329)
... 25 more


三月 10, 2017 12:03:53 下午 org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource [/WEB-INF/applicationContext.xml]; nested exception is java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:343)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:540)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:454)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4717)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5179)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:596)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1805)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:329)
... 25 more

    注意一下,其实重点就一句话,即Could not open ServletContext resource [/WEB-INF/applicationContext.xml],异常也很明显,FileNotException,无法打开ServletContext的资源文件。下面再看一下web.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="3.0" 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">  
    <display-name></display-name>   
        <!-- Spring的log4j监听器 -->  
    <listener>  
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
    </listener>  
      
    <!-- 核心控制器 -->  
    <servlet>  
        <servlet-name>club</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>classpath*:applicationContext.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
      
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  
    <servlet-mapping>  
        <servlet-name>club</servlet-name>  
        <url-pattern>/*</url-pattern>  
    </servlet-mapping>  
    <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
    </welcome-file-list>  
</web-app> 

由于在没用Maven之前,我的spring配置文件——applicationContext.xml是放在WEB-INF根目录下的,在项目运行时都是正常的,重构成Maven项目之后,我的配置文件自然应该放在src下的resources文件夹下了,那么在web.xml中我自然将<init-param>中contextConfigLocation的参数值由WEB-INF/applicationContext.xml修改为classpath:applicationContext.xml了,那么启动tomcat之后依然报错,而且我们从报错信息中可以看出容器依然是在WEB-INF下去找applicationContext.xml,很明显这个文件的位置已经被我们改变了,而且我们也修改了web.xml的配置为何还要从这里去加载呢?原因是我们缺少另一个重要的配置。

解决问题



遇到问题盲目搜索往往不能迅速得到有效的解决方案,所以我们先从官方去寻找线索,看一看spring的官方文档,在The Web的章节中可以发现这样一段话:


简单翻译一下上图标记的小段落:如果不特意指定参数名为contextConfigLoction的<context-parameter>元素,那么spring的ContextLoderListener监听器就会在/WEB-INF/下去寻找并加载该目录下的名为applicationContext.xml这个文件。So,我们应该在web.xml中添加<context-param>标签并再次指定spring核心文件的位置:

[html] view plain copy
  1. <context-param>  
  2.     <param-name>contextConfigLocation</param-name>  
  3.     <param-value>classpath:applicationContext.xml</param-value>  
  4. </context-param>  


这样就OK了,注意这段配置尽量写在靠前的位置,因为在tomcat启动后web项目会先初始化上下文,我们这段配置正是指定了上下文配置的文件位置,在上下文初始化完成之后才应当继续加载其余各种配置,而我们的springMVC的servlet仅仅是springMVC框架的相关配置,就好比struts2的配置一样,项目整体还是由spring去管理的。下面是修改之后的web.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="3.0" 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">  
    <display-name></display-name>   
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:applicationContext.xml</param-value>  
    </context-param> 
        <!-- Spring的log4j监听器 -->  
    <listener>  
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>  
    </listener>  
      
    <!-- 核心控制器 -->  
    <servlet>  
        <servlet-name>club</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <init-param>  
            <param-name>contextConfigLocation</param-name>  
            <param-value>classpath*:applicationContext.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
      
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  
    <servlet-mapping>  
        <servlet-name>club</servlet-name>  
        <url-pattern>/*</url-pattern>  
    </servlet-mapping>  
    <welcome-file-list>  
        <welcome-file>index.jsp</welcome-file>  
    </welcome-file-list>  
</web-app> 

最后再次启动项目,运行正常,spring和springMVC均正常加载并初始化。之前在网上查的有人说修改路径,加星号,又是少jar包,答案千奇百怪,然后都无法解决问题,总之这篇blog希望能对遇到这个异常的朋友有所帮助,The End。


4 0