struts2 之二:action详解

前言

在structs2中,action是其核心功能,而使用structs2框架,主要都是围绕action进行,我们编写的action通常需要实现com.opensymphony.xwork2.Action接口,需要实现的方法时execute方法,但是在实际开发中,编写的action也可以不必实现action接口,而是直接创建一个普通的java类,并添加execute方法就可以,如入门程序的案例,还有一种方式就是继承ActionSupport类,其已经实现了action的execute方法,以上方式,后两者比较常用

接下来将在入门程序的基础上,来介绍action属性

一:action属性
Action中有一个映射框架,主要讲url映射到对应的action,action的配置主要在struts.xml文件中编写,

以下是action的几个常见属性

属性 是否必须 说明
Name 是 action的名字,用于匹配请求的url
Class 否 action实现类的完整类名
Method 否 调用action实现类中指定的方法

需要注意的是,action的name属性有规范,即不允许出现.或者/或者-,另外我们来看看如果只配置一个name属性,class怎么加载?
理论上是框架会调用actionsupport类中的execute方法,该方法的实现仅仅是返回一个success,但是实际上去掉之后,入门程序中跳转正确,但是数据取不到,至少说明的确跳转正确,

下面对method属性进行说明
由之前我们知道通常action的作用是完成一个功能点,但是如果同时又crud方法,显然创建四个action就太麻烦了,这时候就可以使用method属性,至于怎么用,先看一个实例。
即对用户进行增删该查

首先是useraction.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import com.opensymphony.xwork2.ActionSupport;
public class useraction extends ActionSupport{
//查询
public String selectall(){
return SUCCESS;
}
//更新
public String update()
{
return SUCCESS;
}
//删除
public String delete()
{
return SUCCESS;
}
//添加
public String add(){
return SUCCESS;
}
}

这里注意一下,在action中并不一定非要需要写execute方法,也可以自己指定需要的方法,但是必须要在Struts.xml中做相应的配置,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<package name="default" namespace="/" extends="struts-default">
<action name="helloworld" class="com.zwl.action.useraction" method="selectall">
<result name="success">/success.jsp</result>
</action>
<action name="helloworld1" class="com.zwl.action.useraction" method="update">
<result name="success">/success.jsp</result>
</action>
<action name="helloworld2" class="com.zwl.action.useraction" method="delete">
<result name="success">/success.jsp</result>
</action>
<action name="helloworld3" class="com.zwl.action.useraction" method="add">
<result name="success">/success.jsp</result>
</action>
</package>

然后在前台页面写需要调用的action

1
2
3
4
<form action="helloworld.action">
<input type="text" name="msg"/>
<input type="submit"/>
</form>

显然我们发现用此种方法思路清晰,但是太啰嗦,这就是有时需要动态调用action,简称DMI,
先看一个例子,
首先是useraction1.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class useraction1 extends ActionSupport{
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
//查询
public String selectall(){
return "selectall";
}
//更新
public String update()
{
return "update";
}
//删除
public String delete()
{
return "delete";
}
//添加
public String add(){
return "add";
}

这里我们可以通过自定义方法返回不同的值,然后通过result中name属性配置相应不同的值,来返回到不同的界面

1
2
3
4
5
6
7
8
9
10
11
12
13
//这里是是否启用DMI方法,默认是关闭的
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
//这里是否启用开发者模式,这样就不用每次重启服务器
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<action name="useraction1" class="com.zwl.action.useraction1">
<result name="selectall">/success.jsp</result>
<result name="update">/success.jsp</result>
<result name="delete">/success.jsp</result>
<result name="add">/success.jsp</result>
</action>
</package>

好了,配置文件也配置好了,接下来就是在页面中调用DMI方法,一般的格式是actionname!xxx.action

1
2
3
4
<form action="useraction1!delete.action">
<input type="text" name="msg"/>
<input type="submit"/>
</form>

至此动态调用action已完成,接下来将是默认的action配置
默认的action
先看配置实例:

1
2
3
4
5
6
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="helloworld"></default-action-ref>
<action name="helloworld" class="com.zwl.action.useraction" method="selectall">
<result name="success">/success.jsp</result>
</action>

在表单中跳转到一个不存在的action时,则执行设置的默认action,这里需要注意的是每个namespace下,只能有一个默认的action,否则不知道执行那个默认的action

通配符映射
使用通配符,可以将配置量降到最低,不过一定要实现约定好命名规范,即约定优于配置原则
在action配置中,表示所有,可以匹配任意的字符,而{数字}表示第几个通配符,如 _,{1}表示第一个,{2}表示第二个*
接下来模拟一个案例,如下所示
首先是action

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class useractionsave extends ActionSupport{
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String save(){
return "save";
}
}

配置文件

1
2
3
4
5
6
7
8
<action name="useraction*" class="com.zwl.action.useraction{1}" method="{1}">
<result name="save">/success.jsp</result>
</action>
<form action="useractionsave.action">
<input type="text" name="msg"/>
<input type="submit"/>
</form>

最后测试通过

最后介绍一下action的属性接受参数
事实上action中有三种方法

方法一:在Action添加成员属性接受参数
之前的案例都是采用这种方法的,就不多介绍了,不过值得注意的是,参数提交的名称必须和action的属性一致,并且要有set与get方法

方法二: 域模型(Domain Model)
就是先创建一个对象,通过在action中操作其属性来传递参数,相应的先建立一个user对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class user {
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
然后是action
private user use;
public user getUse() {
return use;
}
public void setUse(user use) {
this.use = use;
}
public String save(){
return "save";
}

这里需要注意的是前台参数传递,是action中引用对象的那个属性,其它都一样

1
2
3
4
5
<body>
<form action="useractionsave.action">
<input type="text" name="use.msg"/>
<input type="submit"/>
</form>

方法三: ModelDriven接收参数
使Action实现com.opensymphony.xwork2.ModelDriven(在实现接口时需要使用泛型,否则使用时需要转型)中利用其getModel()方法返回对象模型,从而获得传入的参数。

参数被传入至Action后,会被ModelDriven对象根据参数名自动赋值给User对象相应的属性而生成User对象,并且由getModel()返回。那么我们在Action中就可以利用这个对象了。
注意:传入的参数名需要与对象模型中的成员属性一致。

这里在将上述案例中的action修改一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class useractionsave extends ActionSupport implements ModelDriven<user>{
public String save(){
return "save";
}
private user use=new user();
public user getUse() {
return use;
}
public void setUse(user use) {
this.use = use;
}
@Override
public user getModel() {
// TODO Auto-generated method stub
return use;
}
}

热评文章