一、struts.xml中的包和命名空间
1、Struts2不支持为单独的Action设置命名空间,而是通过为包指定namespace属性来为包下面的所有Action指定共同的命名空间。
如果在配置<package>的时候没有指定namespace属性,则该包下的所有Action处于默认的包空间下
2、例如:
<package name="lee" extends="struts-default"> <action name="login" class="org.crazyit.app.action.LoginAction"> <!-- 定义三个逻辑视图和物理资源之间的映射 --> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> </package>
对于这里的package,定义了name属性,未定义命名空间,则该Action处理的URL为:localhost:8080/项目名/login.action
<package name="lee" extends="struts-default" namespace="/book"> <action name="login" class="org.crazyit.app.action.LoginAction"> <!-- 定义三个逻辑视图和物理资源之间的映射 --> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> </package>
对于这里的package,定义了namespace命名空间,则该Action处理的URL为:localhost:8080/项目名称/book/login.action
注意顺序:①如果请求为/book/login.action,系统首先会查找/book命名空间下的login.action,如果找不到,则会在默认的命名空间查找login.action
②如果请求为/login.action,系统会在跟命名空间(”/“)查找名为login.action,如果找不到,就会转入默认的命名空间
二、使用动态方法调用Action
在一个登陆页面,包含有”登陆“和”注册“两个按钮,如果我们点击了”注册“,我们可以利用javascript来改变form表单的action
function regist() { targetForm = document.forms[0]; targetForm.action = "login!regist"; }
在点击注册之后,我们表单的action属性变为了”login!regist“,意思是交给login这个Action的regist方法处理
三、指定method属性调用Action
在配置<action>元素的时候,我们可以为它定义method属性让Action调用指定的方法:
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="lee" extends="struts-default"> <!-- 配置login Action,处理类为LoginRegistAction 默认使用execute方法处理请求--> <action name="login" class="org.crazyit.app.action.LoginRegistAction"> <!-- 定义逻辑视图和物理视图之间的映射关系 --> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> <!-- 配置regist Action,处理类为LoginRegistAction 指定使用regist方法处理请求--> <action name="regist" class="org.crazyit.app.action.LoginRegistAction" method="regist"> <!-- 定义逻辑视图和物理视图之间的映射关系 --> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> </package> </struts>
在这个struts.xml中,我们定义了两个Action,同时指向了同一个类:LoginRegistAction.java。但是,我们为这两个action分别配置了method属性。
这样子虽然看起来简单明了,但是代码量太多,不好看。
四、使用通配符调用Action
在配置<action>元素的时候,允许在指定name属性时使用模式字符串(即用”*“代表一个或多个任意字符),接下来就可以在class、method属性以及<result>子元素中使用{N}的形式来代表前面第N个星号(*)所匹配的子串,因此我们就可以用一个<action>代替多个“指定method属性的action(就是上边的第三种)”。
1、使用通配符配置method属性
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="lee" extends="struts-default"> <!-- 使用模式字符串定义Action的name,指定所有以Action结尾的请求, 都可用LoginRegistAction来处理,method属性使用{1}, 这个{1}代表进行模式匹配时第一个*所代替的字符串 --> <action name="*Action" class="org.crazyit.app.action.LoginRegistAction" method="{1}"> <!-- 定义逻辑视图和物理视图之间的映射关系 --> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> </package> </struts>
当用户请求/loginAction的时候,会自动调用类“org.crazyit.app.action.LoginRegistAction”中的login方法
2、使用通配符配置class属性
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="lee" extends="struts-default"> <!-- 使用模式字符串定义Action的name,指定所有以Action结尾的请求, 都可用{1}Action来处理, 这个{1}代表进行模式匹配时第一个*所代替的字符串 --> <action name="*Action" class="org.crazyit.app.action.{1}Action"> <!-- 定义逻辑视图和物理视图之间的映射关系 --> <result name="input">/login.jsp</result> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> </package> </struts>
当用户请求/loginAction的时候,会自动调用类org.crazyit.app.action.loginAction中默认的execute方法
3、使用多个通配符,同时配置class和method属性
<action name="*_*" method="{2}" class="actions.{1}" >
在上边的代码中,我们为name属性设置为"*_*",当我们请求/book_save的时候,系统会调用actions.book处理类的save方法来处理用户请求。
在使用通配符的时候,要特别注意一下调用顺序:
对于下边的代码:
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="lee" extends="struts-default"> <!-- 配置name="*"的第二个Action --> <action name="*Action" class="org.crazyit.app.action.TwoAction"> <result name="success">/welcome.jsp</result> </action> <!-- 配置name="*Action"的第一个Action --> <action name="*" class="org.crazyit.app.action.FirstAction"> <result name="success">/welcome.jsp</result> </action> <!-- 配置name为LoginAction的第三个Action --> <action name="LoginAction" class="org.crazyit.app.action.LoginAction"> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> </package> </struts>
我们定义了三个action,分别为"*","*Action","LoginAction"
如果我们请求/RegistAction,该请求会由第一个action进行处理
把上边代码修改顺序:
<?xml version="1.0" encoding="GBK"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN" "http://struts.apache.org/dtds/struts-2.1.7.dtd"> <struts> <package name="lee" extends="struts-default"> <!-- 配置name="*Action"的第二个Action --> <action name="*Action" class="org.crazyit.app.action.TwoAction"> <result name="success">/welcome.jsp</result> </action> <!-- 配置name="*"的第一个Action --> <action name="*" class="org.crazyit.app.action.FirstAction"> <result name="success">/welcome.jsp</result> </action> <!-- 配置name为LoginAction的第三个Action --> <action name="LoginAction" class="org.crazyit.app.action.LoginAction"> <result name="error">/error.jsp</result> <result name="success">/welcome.jsp</result> </action> </package> </struts>
如果我们请求/RegistAction,这时候会由第一个请求处理
由此我们可以得到下边的规律
如果系统发来一条请求:abcAction.action
步骤:
第一、首先查找有没有名为abcAction.action的Action,没有的话进行下一步
第二、搜寻name属性值能够匹配abcAction的Action,例如name为 * 或为*Action,但是*Action并不会比*更有限匹配abcAction的请求,而是先找到哪个Action就会由哪个Action来处理