一、如何写一个struts2框架中的Action
三种方式:
1.只需要类中有一个固定的方法:
public String execute(){
return "..."
}
不需要实现或者继承任何接口或者父类。
当客户端发出的请求和该action匹配到时就会自动执行 execute()方法。
注意: execute方法一定要返回String类型的对象,每一个字符串都可以对应一个跳转的页面.(字符串是可以自己随便定义的,字符串对应哪一个跳转的页面也是自己定义,在struts.xml文件中定义)
2.实现指定的一个接口:com.opensymphony.xwork2.Action
这个接口中只有一个抽象方法 public abstract String execute()throws Exception;
同时还有5个String类型的静态属性:ERROR SUCCESS INPUT NONE LOGIN
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
3.继承一个指定的父类:com.opensymphony.xwork2.ActionSupport
注意:这种是我们之后一直使用的方式。
二、像之前写完servlet类一样,写完action类后需要在struts.xml文件中进行配置.
在struts.xml配置action的目的和作用:通知struts2框架我们写的这个类是一个Action,将来struts2框架中要给这个类创建对象,调用方法以及这个Action加入更多丰富的功能。
例如:
<package name="test" extends="struts-default" namespace="/test">
<action name="MyTest">
<result>/index.jsp</result>
</action>
<action name="test1" class="com.briup.web.action.ActionTest1">
<result name="myFirstAction">/success.jsp</result>
<result name="myError">/error.jsp</result>
</action>
</package>
1)配置中<package>标签及其属性的介绍:
<package name="test" extends="struts-default" namespace="/test">
<package>:一个struts.xml文件中可以配置多个<package>标签,一个<package>标签里面可以配置多个<action>标签,一个<action>标签里面可以配置多个<result>
name="test"
表示给当前package起一个名字为test
作用:1.唯一标识当前这个package。
2.方便package与package之间通过这个名字来实现继承的关系.(像类和类之间的继承一样,要通过父类的名字来继承)
extends="struts-default"
表示当前这个package继承了另外一个名字叫做struts-default的package,这个package在struts2的核心jar包中的struts-default.xml文件中定义的,里面定义了很默认的配置.
注意:我们在struts2中定义的所有package,都会是直接或者间接的继承了struts-default这个package.(像java中所有类都是直接或间接的继承了Object类一样)
namespace="/test"
表示当前package的命名空间为/test,将来这个package里面的所有的action在被访问的时候,路径里面都要加上这个命名空间.
2)配置中<action>标签属性及其子标签介绍:
name="test1"
表示当前配置这个action的名字为test1,这个名字是随便起的,可以和action类的名字相同或者不同.同时将来浏览器中的地址栏里面就是要出现这个名字来访问当前这个action类
class=".."
表示当前配置的action对应的是哪一个java类,我们可以配置一个action,但是这个action可以没有对应任何java类。就像上面配置的MyTest的例子.
<result>
标签表示将来这个action访问完了之后有哪些跳转.
<result name="myError">/error.jsp</result> 表示当前这个action如果返回的字符串是myError,那么页面就跳转到/error.jsp中
注意:每一个action被访问完之后都会有一个字符串类型的返回值,即使访问任何一个java类对应action的时候,这个action也会默认返回字符串:success(前提是这个Action类直接或间接实现Action接口)
<result name="success">/index.jsp</result> 等价于 <result>/index.jsp</result>
<result>标签中的name属性默认值就是success
三、Action的匹配问题:
一般有两种:①直接匹配 ②动态调用
第一种:
<package name="schoolweibo" extends="struts-default">
<action name="user_*" class="indexAction" method="{1}">
<result name="success">/page/user_{1}.jsp</result>
</action>
</package>
其中【*】号代表占位符,而【{1}】表示【*】所对于的action中的方法,比如jsp页面中这样写:
<a href="user_register.action">立即注册</a>
那么对于的indexAction类中的就是register方法。
下面来看一个最少配置的。
<package name="schoolweibo" extends="struts-default">
<action name="*_*" class="{1}Action" method="{2}">
<result name="success">/page/{1}_{2}.jsp</result>
</action>
</package>
这里有两个占位符,第一个代表对于的action类名,第二个代表方法名。如果还有更多占位符,则可以以此类推。
第二种:
<package name="schoolweibo" extends="struts-default">
<action name="register" class="registerAction">
<result name="success">/page/user_Login.jsp</result>
</action>
</package>
注意 :
如果使用这种动态调用的方式需要加上
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
通常由一个表单连接到一个action用来处理表单提交的数据。
表单的 action 一般为: 在 struts.xml中配置的action中name的值!方法名.action
<s:form action="register!register.action">
<s:textfield label="UserName" name="name"/>
<s:submit/>
</s:form>
那么就会调用registerAction类中的register方法。
特殊的action配置:使用通配符来配置
使用前提:原本需要配送的多个action名字或者类的名字是有一定规律的.
例如:原来需要配置这样三个action:
<action name="testCh1" class="com.briup.web.action.ActionTestCh1">
<result>/successCh1.jsp</result>
<result name="error">/errorCh1.jsp</result>
</action>
<action name="testCh2" class="com.briup.web.action.ActionTestCh2">
<result>/successCh2.jsp</result>
<result name="error">/errorCh2.jsp</result>
</action>
<action name="testCh3" class="com.briup.web.action.ActionTestCh3">
<result>/successCh3.jsp</result>
<result name="error">/errorCh3.jsp</result>
</action>
这时候,我们就可以使用通配符配置一个action来代替这三个action:
<action name="test*" class="com.briup.web.action.ActionTest{1}">
<result>/success{1}.jsp</result>
<result name="error">/error{1}.jsp</result>
</action>
{1}代表的时候前面name属性中所出现的第一个 * 号如果有第二个 * 号,可以用{2}来表示。
test* 就是将来在浏览器中输入的这个action名字,如果输入的时候test1,那么这个*号就代表1,如果输入的是testlogin,那么这个*号就是代表login.
注意:如果原本需要配置的多个action没有非常明显的规律,那么就不要用这种方式来配置了.
四、action的特点及其访问
特点:
servlet是线程不安全的,因为servlet是单例。
struts2框架中的action是线程安全的,因为每次访问都会创建一个新的Action对象.所有在action里面可以随便的定义成员变量(只有成员变量才有线程安全的问题)
访问:
默认情况下,访问action的时候,使用namespace/actionName.action或者namespace/actionName就可以访问的到.
注意:
访问action时不添加后缀名需要在 web.xml 中修改的过滤器的url-pattern
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
例如:
<package name="test" extends="struts-default" namespace="/test">
<action name="test1" class="类A">
<result>/index.jsp</result>
</action>
</package>
http://ip地址:端口号/项目名字/test/test1.action
或者
http://ip地址:端口号/项目名字/test/test1
访问成功页面就会跳转到index.jsp页面了
但是由于不加任何后缀名也可以访问到这个action,这样容易和其他资源的访问产生冲突,比如servlet的访问(本来是访问项目的servlet的,但是Struts2框架却当成了这是访问action的请求来处理).
所以我们需要配置一下,把action访问规定成,只能使用后缀名.action或者是.do 或者是其他形式来访问.
//可以使用.action或者.do来访问
<constant name="struts.action.extension" value="action,do"></constant>
//只能使用.action
<constant name="struts.action.extension" value="action"></constant>
五、访问action的时候,action中方法的调用
1.默认情况下,访问action的时候会调用action中的execute方法,这个方法执行完返回一个字符串,然后根据字符串进行跳转.
2.可以在<action>标签里面加上一个method属性,来指明将来访问这个action的时候会调用哪一个方法.
例如:
<action name="test" class=".." method="login">
注意:两个不同名字的action可以对应的是相同的一个java类.
<action name="test1" class="类A" method="login">
<action name="test2" class="类A" method="register">
这样使用test1和test2辆个不同名字的action就是访问到同一个类中的两个不同的方法:login和regist方法.但是login方法和register方法必须和execute方法类似的,都是返回String的值.
3.地址栏中动态指定要调用的方法
例如:
<package name="test" extends="struts-default" namespace="/test">
<action name="MyTest" class="类A">
<result>/index.jsp</result>
</action>
</package>
类A里面有俩个方法:register login
默认情况下地址栏中通过MyTest.action来访问这个action会访问到它的execute方法,同时我们还可以在地址栏中动态的指定要访问的方法:
MyTest!login.action 这样就能访问到名字为MyTest的action对应类A中的login方法了.
http://ip地址:端口号/项目名字/test/MyTest!login.action
原文:http://blog.csdn.net/qq_22063697/article/details/51891908