`

struts.xml中的include标签和package标签以及action标签的name属性

 
阅读更多

struts.xml中的<include/>标签


当系统变大后,可能会导致struts.xml内容非常多,这时我们就可以采用模块化的方式,将不同的配置文件分散在不同的配置里面,然后由struts.xml将它们统一的加载进来。比如struts_1.xmlstruts_2.xmlstruts_3.xml三个文件,分别是针对不同模块的配置,最后就可以由struts.xml统一将其整合起来,整合的方式就是把这它们包含进来即可。
<include file="struts_1.xml"/>

<include file="struts_2.xml"/>

<include file="struts_3.xml"/>
struts_1.xml或者struts_2.xml中的配置方式与struts.xml中的配置方式是一模一样的。即它们顶部都必须有XML声明DTD,它们DTD都是相同的,接下来是<struts/>根元素不能认为struts_1.xml是被包含文件,便将顶部XML声明和DTD省略掉,这是不可以的。
最后由struts.xml统一引入,于是系统加载,便将struts_1.xml及struts_2.xml等的配置都加载到内存中,这就相当于进行模块化的配置。对于大中型的系统来说,是不可避免的会使用模块化的配置方式的

 

struts.xml中<package name="#"/>的命名
其中struts.xml中<package/>的name可随意命名,不会影响到其它的任何东西,它的name属性的作用仅仅是用来标识<package/>的,以便另外的<package/>可以继承

 

<package name="struts-default" abstract="true">
在struts-default.xml的第73行配置<package/>时,声明了一个abstract="true"属性,我们发现这个包中声明了结果类型、拦截器等等,却唯独没有声明<action/>的配置,但是在我们自己定义的struts.xml中有若干个<action/>的配置,因此abstract="true"表示当前包是抽象包,所以当前包中不允许出现<action/>的配置
抽象包的作用极类似于Java抽象类。自己不能实例化,只能被继承,然后由子类实现它的若干方法,最后由子类实例化。所以struts-default包中不能包含任何<action/>定义,具体的定义则是由其子包来定义的

 

<package name="struts2" extends="struts-default">中的extends的含义
Struts2中可以用包机制区分不同的Action,而将功能相似的Action放到一个package中,类似于Java中包的机制,不同的是Struts2的包支持多继承,如下所示
<package name="struts2" extends="struts-default, jfreechart-default">并且Struts2的package之间,又是可以实现继承关系的,继承之后就可以把被继承的package中的所有东西都拿来使用了,所以它就相当于将<package name="struts-default"/>的全部东西都继承过来了,于是才可以直接把struts-default.xml包中的所有结果类型、拦截器等都拿来供我们使用,如果我们的包不继承Struts2提供的struts-default包,那么我们很多工作都会变得无法完成。在Struts2应用启动时会自动读取struts-default.xml,将该文件定义的所有东西加载到内存中,接下来再加载当前应用的struts.xml文件,然后将内存中struts-default.xml的信息读取过来,然后才会加入到我们当前的应用中,并且在default.properties的第180行和181行有如下代码
### A list of configuration files automatically loaded by Struts
struts.configuration.files=struts-default.xml,struts-plugin.xml,struts.xml
翻译:被Struts自动加载的一个配置文件列表
应用启动时加载顺序是:先加载struts-default.xml次之struts-plugin.xml最后struts.xml
因此:后者中的配置信息就可以覆盖掉前者中的配置信息

<package/>的namespace属性
若未配置<package/>标签的namespace属性,则相当于namespace="",表示当前package位于默认命名空间里。命名空间要以斜线开头,假设包的namespace="/hello",且表单action="login",然后在页面中点击提交按钮,这时在页面中将显示The requested resource (/struts2/login) is not available
这时可将表单改为action="/hello/login"或在表单中使用namespace和action属性分开来写
<form action="login" namespace="/hello">注意此时若写成login.action则会出错
修改完表单action后,再次提交时显示的却是The requested resource (/struts2/hello/login) is not available。这是因为根本就不存在这个路径,正确的路径应该是/struts2/hello/login.action
所以配置包的namespace后,须手工添加action后缀,即action="/hello/login.action"
再次提交则正常显示,且浏览器显示的是http://127.0.0.1:8088/struts2/hello/login.action
另外:假设发送action="/test/login.action"请求,但struts.xml中根本就没有命名空间为test的包
当Struts2发现该命名空间不存在时,它会到默认命名空间下寻找login的<action/>的信息
假设发送action="/hello/login.action"请求,当/hello的namespace下不存在login.action时
Struts2会尝试到默认的命名空间下去寻找有没有名字叫做login的<action/>信息
若默认命名空间下不存在名为login的<action/>的信息,则会报告资源找不到的错误


Struts2还支持根命名空间【"/"】
当直接请求contextPath下的资源时,它会先到根命名空间下寻找匹配的Action
例如请求http://127.0.0.1:8088/project/BB.action时,Strtus2会首先到"/"命名空间下去找这个Action
服务器的根http://127.0.0.1:8088/
网 站的根http://127.0.0.1:8088/struts2_demo/
假设JSP中写成<a href=“/login.jsp”></a>,则实际指向的是http://127.0.0.1:8088/login.jsp
JSP中的根指的是服务器的根。而命名空间的斜杠代表网站的根,也叫项目的根或者应用的根


struts.xml中<action/>的name值的开头不允许加斜杠
这是由default.properties的第109行属性决定,即struts.enable.SlashesInActionNames默认为FALSE
比如说在struts.xml中,不指定<package/>的namespace属性,并写成<action name="hello/login">
再在表单中写成action="<%=request.getContextPath()%>/hello/login.action",此时仍可正常访问
但要注意:此时不能写成<action name="/hello/login"/>,否则在运行时仍会报告404错误
总之直接使用命名空间就是了,不建议修改struts.enable.SlashesInActionNames属性,保持默认配置即可

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics