天天看點

關于Struts2中struts.xml檔案分層問題

沒事折騰struts2,遇到異常,浪費好長時間,于是幹脆把所有可能的異常都給跑一遍,來個痛快的。

檔案的結構

WEB-INF

      |------configs

                   |-------struts-common.xml

                   |-------struts.xml

      |------web.xml

遇到的異常:

WARNING: Could not find action or result: /Pro_struts2/common/login!preLogin
There is no Action mapped for action name login!preLogin. - [unknown location]
	at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185)
	at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
	at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:37)
	at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
	at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:552)
	at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
	at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2441)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2430)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:724)
           

一般情況下struts的配置檔案都是放在src檔案目錄下。我想把這些配置檔案放到WEB-INF目錄下面,然後在web.xml中告訴系統這些檔案的位置。xml檔案

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	
	<display-name>Pro_struts2</display-name>
	
	<!-- 注冊struts架構過濾器 -->
	<filter>
		<filter-name>struts</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
		<init-param>
			<description>指定struts.xml檔案位置</description>
			<param-name>config</param-name>
			<span style="color:#ff0000;"><param-value>configs/struts.xml</param-value>
</span>		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>struts</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>
           

參見紅色字型部分,錯誤原因:此處路徑是相對于web.xml本身,是以路徑應該修改為“../configs/struts.xml”

修改好後,伺服器啟動報錯:

SEVERE: Dispatcher initialization failed
com.opensymphony.xwork2.inject.DependencyException: com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=com.opensymphony.xwork2.ObjectFactory, name='default'] in public void com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.setObjectFactory(com.opensymphony.xwork2.ObjectFactory).
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:144)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMethods(ContainerImpl.java:113)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:90)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:86)
	at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:71)
	at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:67)
	at com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:150)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:76)
	at com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:116)
	at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:490)
	at com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
	at com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
	at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
	at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
	at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:257)
	at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)
	at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:445)
	at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:489)
	at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
	at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:57)
	at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
	at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4809)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5485)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
	at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:670)
	at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1839)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:724)
Caused by: com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=com.opensymphony.xwork2.ObjectFactory, name='default'] in public void com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.setObjectFactory(com.opensymphony.xwork2.ObjectFactory).
	at com.opensymphony.xwork2.inject.ContainerImpl.createParameterInjector(ContainerImpl.java:239)
	at com.opensymphony.xwork2.inject.ContainerImpl.getParametersInjectors(ContainerImpl.java:229)
	at com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.<init>(ContainerImpl.java:293)
	at com.opensymphony.xwork2.inject.ContainerImpl$3.create(ContainerImpl.java:117)
	at com.opensymphony.xwork2.inject.ContainerImpl$3.create(ContainerImpl.java:114)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:141)
	... 38 more

Jul 02, 2014 3:34:30 PM org.apache.catalina.core.StandardContext filterStart
SEVERE: Exception starting filter struts
com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=com.opensymphony.xwork2.ObjectFactory, name='default'] in public void com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.setObjectFactory(com.opensymphony.xwork2.ObjectFactory). - Class: com.opensymphony.xwork2.inject.ContainerImpl
File: ContainerImpl.java
Method: addInjectorsForMembers
Line: 144 - com/opensymphony/xwork2/inject/ContainerImpl.java:144:-1
	at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:501)
	at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:74)
	at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:57)
	at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
	at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:260)
	at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105)
	at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4809)
	at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5485)
	at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
	at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
	at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
	at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
	at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:670)
	at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1839)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:724)
Caused by: com.opensymphony.xwork2.inject.DependencyException: com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=com.opensymphony.xwork2.ObjectFactory, name='default'] in public void com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.setObjectFactory(com.opensymphony.xwork2.ObjectFactory).
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:144)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMethods(ContainerImpl.java:113)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:90)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectors(ContainerImpl.java:86)
	at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:71)
	at com.opensymphony.xwork2.inject.ContainerImpl$1.create(ContainerImpl.java:67)
	at com.opensymphony.xwork2.inject.util.ReferenceCache$CallableCreate.call(ReferenceCache.java:150)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
	at java.util.concurrent.FutureTask.run(FutureTask.java:166)
	at com.opensymphony.xwork2.inject.util.ReferenceCache.internalCreate(ReferenceCache.java:76)
	at com.opensymphony.xwork2.inject.util.ReferenceCache.get(ReferenceCache.java:116)
	at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:490)
	at com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:530)
	at com.opensymphony.xwork2.inject.ContainerImpl$6.call(ContainerImpl.java:528)
	at com.opensymphony.xwork2.inject.ContainerImpl.callInContext(ContainerImpl.java:584)
	at com.opensymphony.xwork2.inject.ContainerImpl.inject(ContainerImpl.java:528)
	at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:257)
	at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:67)
	at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:445)
	at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:489)
	... 19 more
Caused by: com.opensymphony.xwork2.inject.ContainerImpl$MissingDependencyException: No mapping found for dependency [type=com.opensymphony.xwork2.ObjectFactory, name='default'] in public void com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.setObjectFactory(com.opensymphony.xwork2.ObjectFactory).
	at com.opensymphony.xwork2.inject.ContainerImpl.createParameterInjector(ContainerImpl.java:239)
	at com.opensymphony.xwork2.inject.ContainerImpl.getParametersInjectors(ContainerImpl.java:229)
	at com.opensymphony.xwork2.inject.ContainerImpl$MethodInjector.<init>(ContainerImpl.java:293)
	at com.opensymphony.xwork2.inject.ContainerImpl$3.create(ContainerImpl.java:117)
	at com.opensymphony.xwork2.inject.ContainerImpl$3.create(ContainerImpl.java:114)
	at com.opensymphony.xwork2.inject.ContainerImpl.addInjectorsForMembers(ContainerImpl.java:141)
	... 38 more
           

錯誤原因,當struts.xml檔案不再src下時,無法自動關聯到strtus-default.xml檔案,是以需要以下配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	
	<display-name>Pro_struts2</display-name>
	
	<!-- 注冊struts架構過濾器 -->
	<filter>
		<filter-name>struts</filter-name>
		<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
		<init-param>
			<description>指定struts.xml檔案位置</description>
			<param-name>config</param-name>
			<param-value><span style="color:#ff0000;">struts-default.xml,</span>../configs/struts.xml</param-value>
		</init-param>
	</filter>
	
	<filter-mapping>
		<filter-name>struts</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>
           

這樣處理之後,啟動就不會報錯了。

由于struts檔案也被分割成兩個檔案,struts.xml 使用include标簽将sturts-common.xml包含進來。sturts.xml檔案内容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- 這些屬性可以再struts的StrutsConstant.java中找到 -->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.custom.i18n.resources" value="MessageResource"></constant>
	<constant name="struts.i18n.encoding" value="utf-8"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
	<include file="struts-common.xml"></include>
</struts>
           

伺服器啟動沒有問題,但是無法通路到sturts-common.xml中的Action,報錯資訊如下

SEVERE: Could not find action or result
/Pro_struts2/common/login!preLogin
There is no Action mapped for action name login. - [unknown location]
	at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:185)
	at org.apache.struts2.impl.StrutsActionProxy.prepare(StrutsActionProxy.java:63)
	at org.apache.struts2.impl.StrutsActionProxyFactory.createActionProxy(StrutsActionProxyFactory.java:37)
	at com.opensymphony.xwork2.DefaultActionProxyFactory.createActionProxy(DefaultActionProxyFactory.java:58)
	at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:552)
	at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
	at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2441)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2430)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:724)
           

錯誤原因:雖然sturts.xml在configs檔案夾中,但是編譯後struts.xml檔案的位置是在WEB-INF/classes下面的,是以相對路徑應該相對于classes檔案夾。修改如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
	"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- 這些屬性可以再struts的StrutsConstant.java中找到 -->
	<constant name="struts.devMode" value="true"></constant>
	<constant name="struts.custom.i18n.resources" value="MessageResource"></constant>
	<constant name="struts.i18n.encoding" value="utf-8"></constant>
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
	<include file="<span style="color:#ff0000;">../configs/</span>struts-common.xml"></include>
</struts>
           

繼續閱讀