<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC 
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" 
	"http://struts.apache.org/dtds/struts-2.1.dtd">

<struts>

<!-- 
**  -> struts.class.reloading.acceptClasses                                  **
**  -> struts.convention.actionNameBuilder                                   **
**  -> struts.convention.result.path                                         **
**  -> struts.convention.classes.reload                                      **
**  -> struts.convention.action.mapAllMatches                                **
**  -> struts.convention.relative.result.types                               **
**  -> actionPackages                                                        **
**  -> struts.convention.action.name.lowercase                               **
**  -> struts.convention.package.locators.disable                            **
**  -> struts.convention.package.locators                                    **
**  -> struts.convention.action.checkImplementsAction                        **
**  -> struts.convention.action.fileProtocols                                **
**  -> struts.convention.action.disableScanning                              **
**  -> struts.convention.exclude.parentClassLoader                           **
**  -> struts.convention.default.parent.package                              **
**  -> struts.class.reloading.watchList                                      **
**  -> struts.class.reloading.reloadConfig                                   **
**  -> struts.convention.exclude.packages                                    **
**  -> struts.convention.package.locators.basePackage                        **
**  -> struts.convention.conventionsService                                  **
**  -> struts.convention.action.name.separator                               **
**  -> struts.configuration.files                                            **
**  -> struts.convention.redirect.to.slash                                   **
**  -> struts.convention.action.alwaysMapExecute                             **
**  -> struts.convention.interceptorMapBuilder                               **
**  -> struts.convention.action.suffix                                       **
**  -> struts.convention.result.flatLayout                                   **
**  -> struts.convention.resultMapBuilder                                    **
**  -> struts.convention.actionConfigBuilder                                 **
 -->

	<!-- 设置默认的local属性 -->
	<constant name="struts.locale" value="zh_CN"/>

	<!-- 指定Web应用的默认编码集,相当于调用 HttpServletRequest的setCharacterEncoding方法 -->
	<constant name="struts.i18n.encoding" value="UTF-8" />

	<!-- 指定需要Struts2处理的请求后缀,该属性的默认值是value="action,,"
		  如果需要指定多个请求后缀,则多个后缀之间以英文逗号隔开。
		  扩展名可以指定为空(, 或者action,,),但是servlet会映射地址为/services/*,这个地址也变成struts2控制范围的地址了,
		  如果按默认的配置会报找不到action的错误。
		 
		  不设置该常量时,当web.xml配置为/*时,所有的*.action和没有后缀的请求都被当作Action交由Struts2处理。
		  明确设置value="action"时,哪怕web.xml配置为/*,struts也只会处理所有*.action的请求,
		  其他后缀(.do)和无后缀的请求都会被忽略,从而继续在web.xml定义的资源中寻找。 -->
	<constant name="struts.action.extension" value="action" />

	<!-- 设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭 -->
	<constant name="struts.serve.static.browserCache" value="false" />

	<!-- 当 struts.xml文件的内容改变后,系统是否自动重新加载该文件,默认值为false(生 产环境下使用),开发阶段最好打开 -->
	<constant name="struts.configuration.xml.reload" value="true" />

	<!-- 开发模式下使用,这样可以打印出更详细的错误信息 -->
	<constant name="struts.devMode" value="true" />

	<!-- 设置视图主题,默认为xhtml(simple、xhtml、css_xhtml、ajax)-->
	<constant name="struts.ui.theme" value="simple" />

	<!-- 该属性指定Struts2中的action由Spring容器创建 -->
	<!-- 当struts2跟spring整合后,如果在struts.xml中Action.class指定的是ClassName,而不是BeanID,
		那么struts2对象池自己负责Action对象的创建,但是Action对象依赖关系的注入由spring负责。
		struts2优先用spring来构造Action对象,在spring中配置的Action对象必须设置属性scope="prototype",
		使用struts.xml中Action.class指定的名称作为BeanID在spring的applicationContext.xml中查找,
		找到则使用spring容器创建的Action实例;如果没找到,则struts2对象池负责构造这个对象。但是,依赖关系的自动装配还是得由spring完成。 -->
	<constant name="struts.objectFactory" value="spring" />

	<!-- 指定spring框架的装配模式,装配方式有: name、type、auto 和  constructor (name是默认装配模式) -->
	<constant name="struts.objectFactory.spring.autoWire" value="type" />

	<!-- 指定上传文件时的临时存放目录,默认使用 javax.servlet.context.tempdir -->
	<constant name="struts.multipart.saveDir" value="/tmp_file" />

	<!-- 该属性指定Struts2文件上传中整个请求内容允许的最大字节数 -->
	<constant name="struts.multipart.maxSize" value="2097152" />

	<!-- 设置是否支持动态方法调用,true为支持,false不支持。要实现零配置,就需要动态方法调用 -->
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />

	<!-- 设置是否可以在action中使用斜线,默认为false不可以,想使用需设置为true -->
	<constant name="struts.enable.SlashesInActionNames" value="true" />

	<!-- 是否允许使用表达式语法,默认为true. -->
 	<constant name="struts.tag.altSyntax" value="true" />

 	<!-- 设置是否每次请求,都重新加载资源文件,默认值为false,开发时可设置为true以便调试 -->
 	<constant name="struts.i18n.reload" value="true" />

	<!-- 设置要加载的国际化资源文件,以逗号分隔 -->
	<constant name="struts.custom.i18n.resources" value="application" />

	<!-- 设置struts自动加载的文件列表,以逗号分隔 -->
	<constant name="struts.configuration.files" value="struts-default.xml,struts-plugin.xml,struts.xml" />


    <!-- struts-convention-plugin设置 -->
    <!-- 指定结果页面路径。 convention插件会自动在此路径中寻找文件,放到WEB-INF的目的是保护文件资源,只有通过程序内部跳转才能访问,
    	  权限拦截器或其他权限处理只要加到action上就可以了 -->
    <constant name="struts.convention.result.path" value="/WEB-INF/pages/" />
    
    <!-- 设置默认的父包,一般都设置一个default包继承自struts-default。大部分类再继承default。如果需要特殊的包,只能在action中再指定父包  -->
	<constant name="struts.convention.default.parent.package" value="default" />


	<!-- include -->
	<!-- include节点是struts2中组件化的方式, 可以将每个功能模块独立到一个xml配置文件中, 然后用include节点引用 -->
	<!-- <include file="struts-default.xml" /> -->
	
	<!-- package -->
	<!-- 在struts2框架中是通过package来管理action、result、interceptor、interceptor-stack等配置信息的。
		 package提供了将多个Action组织为一个模块的方式。它的常用属性有:
    	 • name: 		必填属性,包的name必须是唯一的, 用于指定包的名字。
    	 • extends:		可选属性, 当一个包通过配置extends属性继承了另一个包的时候,该包将会继承父包中所有的配置,包括action、result、interceptor等。
    	 				由于包信息的获取是按照配置文件的先后顺序进行的,所以父包必须在子包之前被定义。
    	 				通常配置struts.xml的时候,都继承一个名为“struts-default”的包,这是struts2中内置的缺省包,可以满足大多数使用场景。
		 • namespace:	可选属性,用来指定该包的命名空间。namespace主要是针对大型项目中Action的管理,更重要的是解决Action重名问题,
		 				因为不在同一个命名空间的Action可以使用相同的Action名称。命名空间影响到url的地址,例如命名空间为/user那么访问的地址
		 				为http://localhost:8080/webapp/user/login.action。如果没有为某个包指定namespace属性,该包将使用默认的命名空间,默认的命名空间总是""。
		 				当设置了命名空间为“/”,即指定了包的命名空间为根命名空间时,此时所有根路径下的Action请求都会去这个包中查找对应的资源信息。
		 • abstract:	设置package的属性为抽象的(true/false),抽象的package不能定义action。 -->
	
	<!-- global-results -->
	<!-- global-results标签用于设置package范围内的全局结果集。在多个Action返回相同逻辑视图的情况下,可以通过<global-results>标签统一配置这些物理视图所对应的逻辑视图。
    	<package>
	    	<global-results>
	    		<result name="error">/error.jsp</result>
	    	</global-results>
    	</package> -->
	
	<!-- exception-mapping -->
	<!-- exception-mapping与global-exception-mapping 这两个标签都是用来配置发生异常时对应的视图信息,只不过一个是Action范围的,一个是package范围的,
		当同一类型异常在两个范围都被配置时,Action范围的优先级要高于包范围的优先级。
		<action>
			<exception-mapping result="逻辑视图" exception="异常类型" />
		</action>
		<package>
			<global-exception-mappings>
				<exception-mapping result="error" exception="java.lang.Throwable" />
			</global-exception-mappings>
		</package> -->
	
	<!-- default-class-ref -->
	<!-- default-class-ref 在配置Action的时候,如果没有为Action指定具体的class值时,系统将自动引用package的default-class-ref标签中所指定的类。
		在Struts2框架中,系统默认的class为ActionSupport,该配置我们可以在xwork的核心包下的xwork-default.xml文件中找到。
		一旦更改这个配置,“defaultStack”将不再被引用,需要手动添加。
		<package name="struts-default" abstract="true">
			<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
		</package> -->
	 
	 <!-- interceptors -->
	 <!-- interceptors 标签可以向Struts2框架中注册package范围内的拦截器或者拦截器栈,一般多用于自定义拦截器或拦截器栈的注册。
		<interceptors>
			<interceptor name="拦截器名" class="拦截器类"/>
			<interceptor-stack name="拦截器栈名" />
				<interceptor-ref name="拦截器名" />
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
		</interceptors>
		<package name="securePackage" namespace="secure" extends="struts-default">
			<interceptors>
				<interceptor name="authenticationInterceptor" 
					class="com.jaeson.struts.interceptor.AuthenticationInterceptor" />
				<interceptor-stack name="secureStack">
					<interceptor-ref name="authenticationInterceptor" />
					<interceptor-ref name="defaultStack" />
				</interceptor-stack>
			</interceptors>
			<default-interceptor-ref name="secureStack" />
		</package> -->
		
	<!-- interceptor-ref -->
	<!-- interceptor-ref 标签可以定义action 范围内的拦截器引用:
		<action name="FileUploadAction" class="fileUploadAction">
			<interceptor-ref name="fileUpload">
				<param name="allowedTypes">
					image/bmp,image/png,image/gif,image/jpeg,image/jpg
				</param>
				<param name="maximumSize">1024*1024</param>
			</interceptor-ref>
			<interceptor-ref name ="defaultStack" />
		</action> -->
	 
	 <!-- default-interceptor-ref -->
	 <!-- default-interceptor-ref 标签用来设置package范围内所有Action所要引用的默认拦截器栈信息。
	 	事实上我们的包继承了struts-default包以后,使用的是Struts2的默认设置。我们可以在struts-default.xml中找到相关配置:
		<package name="struts-default" abstract="true">
			<default-interceptor-ref name="defaultStack" />
		</package> -->
	
	<!-- result-types -->
	<!-- result-types标签定义package范围内的result类型,默认值为dispatcher。
		<package name="struts-default" abstract="true">
			<result-types>
	            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
	            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
	            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
	            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
	            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
	            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
	            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
	            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
	            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
	            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
	            <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
        	</result-types>
        </package> -->
        
	<!-- action -->
	<!-- Struts2中的Action采用了低侵入式的设计,Struts2不要求Action类继承任何的Struts2的基类或实现Struts2接口。
		 (但是,我们为了方便实现Action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport,
		 并重写此类里的public String execute() throws Exception方法。因为此类中实现了很多的实用接口,提供了很多默认方法,
		 这些默认方法包括获取国际化信息的方法、数据校验的方法、默认的处理用户请求的方法等,这样可以大大的简化Action的开发。)
		Struts2中通常直接使用Action来封装HTTP请求参数,因此,Action类里还应该包含与请求参数对应的属性,并且为属性提供对应的getter和setter方法。-->
		
	<!-- action配置:一个Action可以被多次映射(只要action配置中的name不同)。
		name:	action名称
		class: 	对应类的全限定类名,默认值为com.opensymphony.xwork2.ActionSupport
		method: 调用Action中的方法名,默认值为execute -->
	<!-- result节点配置:
		name : result名称, 对应Action返回逻辑视图名称,默认为success
		type : result类型, 默认为dispatcher -->
	<!-- param参数配置:
		name:对应Action中的getter/setter方法,用于设置Action的参数初始化 -->
	<!-- 
		<action name="login" class="com.jaeson.struts.Action.LoginAction">
			<result name="success" type="dispatcher">/login.jsp</result>
			<param name="url">http://www.sina.com</param>
		</action> -->
	
	<!-- action调用 -->
	<!-- 动态方法调用:必须设置struts.enable.DynamicMethodInvocation常量的值为true(默认值)
		 <form method="post" action="userManager!login.action"> -->
	<!-- 为Action指定method属性:
		 <action name="userLogin" class="com.jaeson.struts2.action.UserManagerAction" method="login"> -->
	<!-- 通配符映射:
		 <action name="user_*" class="com.jaeson.struts2.action.UserManagerAction" method="{1}">  -->

	<!-- ActionContext -->
	<!-- Struts2中的Action并没有和任何Servlet API耦合,这样框架更具灵活性,更易测试。
		但是,对于web应用的控制器而言,不访问Servlet API几乎是不可能的,
		例如跟踪HTTP Session状态等。Struts2框架提供了一种更轻松的方式来访问Servlet API。
		Struts2提供了一个ActionContext类(当前Action的上下文对象),通过这个类可以访问Servlet API。
		Struts2通过ActionContext来访问Servlet API,让Action彻底从Servlet API中分离出来,最大的好处就是可以脱离Web容器测试Action。
		ActionContext context = ActionContext.getContext();
		Map session = context.getSession(); -->
	
	<!-- package extends struts的智能默认值 -->
	<package name="default" extends="struts-default">
		<global-results>
    		<result name="error">/error.jsp</result>
    		<result name="login">/login.jsp</result>  
    	</global-results>
    	<global-exception-mappings>
			<exception-mapping exception="java.lang.Throwable" result="error" />
		</global-exception-mappings>
		<!-- 使用智能默认值action.class="ActionSupport" result.name="success" result.type="dispatcher" -->
		<action name="Input">
			<result>/default.jsp</result>
		</action>
		<action name="HelloWorld" class="com.jaeson.struts.action.HelloWorld">
			<result name="success">/helloworld.jsp</result>
		</action>
		
		<action name="Online" class="onlineAction" method="online">
			<result name="success">/online.jsp</result>
		</action>
		
		<action name="AddUserAction" class="userAction">
			<result name="success">/success.jsp</result>
			<result name="input">/addUser.jsp</result>
		</action>
		<action name="AddUserModelAction" class="userModelAction">
			<result name="success">/successByModel.jsp</result>
			<result name="input">/addUserModel.jsp</result>
		</action>
		
		<action name="ForwardAction" class="forwardAction">
			<result name="success">/showServlet</result>
		</action>
		
		<!-- validator test -->
		<action name="ValidatorAction" class="validatorAction">
			<result name="success">/welcome.jsp</result>
			<result name="input">/validator.jsp</result>
		</action>
		
		<!-- prepare 验证失败返回列表信息丢失,使用prepare每次提交时将list数据放入request中 -->
		<action name="PrepareAction" class="prepareAction">
			<result name="success">/welcome.jsp</result>
			<result name="input">/prepare.jsp</result>
		</action>

		<!-- upload and download -->
		<action name="FileUploadAction" class="fileUploadAction">
			<!-- 配置 fileupload 的拦截器 -->
			<interceptor-ref name="fileUpload">
				<!-- 可以支持上传的文件类型 -->
				<param name="allowedTypes">
					image/bmp,image/png,image/gif,image/jpeg,image/jpg  
				</param>
				<!-- 设置上传文件的大小不能超过1M -->
				<param name="maximumSize">2097152</param>
			</interceptor-ref>
			<interceptor-ref name ="defaultStack" />
			
			<param name="savePath">/upload</param>
			<result name="success">/successFileUpload.jsp</result>
			<result name="input">/fileUpload.jsp</result>
		</action>
		
		<action name="FileDownloadAction" class="fileDownloadAction">
			<param name="savePath">/upload</param>
			<result name="success" type="stream">
				<param name="contentType">text/plain</param>
				<param name="contentDisposition">attachment;fileName="${fileName}"</param>
				<param name="inputName">inputStream</param>
			</result>
		</action>

		<!-- return json without jsonresult -->
		<action name="JSONAction" class="jsonAction" method="writeJSON" />
		
	</package>
	
	<!-- use struts json plugin jsonresult -->
	<package name="json" extends="json-default" namespace="/json">
		<action name="JSONAction" class="jsonAction">
			<result type="json">
				<!-- 指定内容类型,默认为application/json,IE浏览器会提示下载 -->
				<param name="contentType">text/html</param>
				<!-- 默认将会序列化所有有返回值的getter方法的值,而无论该方法是否有对应属性。
					root代表从哪里开始序列化,如果root是对象则会将root对象中所有的getter方法都进行序列化。 -->  
				<!-- <param name="root">map</param> -->
				<!-- 指定是否序列化空的属性,默认为false,序列化空属性,对象为null,string为"" -->
				<!-- <param name="excludeNullProperties">true</param> -->
				<!-- 这里指定将序列化map中的那些属性 -->
				<!-- <param name="includeProperties">userList.*</param> -->
				<!-- 这里指定将要从map中排除那些属性,这些排除的属性将不被序列化,一般不与上边的参数配置同时出现。
					如果相同属性同时指定exclude和include,则exclude的优先级高,因此不序列化该属性-->  
				<!-- <param name="excludeProperties">
					SUCCESS
				</param> -->
			</result>
		</action>
	</package>
	
	<!-- namespace="/" -->
	<package name="securePackage" namespace="secure" extends="struts-default">
		<interceptors>
			<interceptor name="authenticationInterceptor" 
				class="com.jaeson.struts.interceptor.AuthenticationInterceptor" />
			<interceptor name="authorityInterceptor" 
				class="com.jaeson.struts.interceptor.AuthorityInterceptor" />
			<interceptor-stack name="secureStack">
				<interceptor-ref name="authenticationInterceptor" />
				<interceptor-ref name="authorityInterceptor" />
				<interceptor-ref name="defaultStack" />
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="secureStack"/>
		<!-- 下面定义的结果对所有的Action都有效,必须放在Action定义之前 -->
		<global-results>
    		<result name="error">/error.jsp</result>
    		<result name="login">/login.jsp</result>  
    	</global-results>
    	<global-exception-mappings>
			<exception-mapping exception="java.lang.Throwable" result="error" />
		</global-exception-mappings>
	</package>
	
</struts>