上篇文章讲了实现Action的三种方式,以及如何在Action中取得Servlet API。那么这篇文章就讲怎么配置Action。
1.Action的基本配置
Struts2使用package包来组织Action,在struts.xml中通过在<package>标签中使用<action>标签来配置Action。
<action>标签中有两个最常用的属性name和class
- name属性:指定Action的名字,即指明请求该Action的URL。比如一个Action的name为user,则请求该Action的URL为user.action或user。
- class属性:指定Action所对应的类,该属性是可选的,如果没有指定,则默认调用ActionSupport类。
一个示例
<action name = "user" class = "com.codeliu.action.UserAction">
......
</action>
Action只是一个逻辑控制器,不直接对用户的请求生成任何相应,因此,Action处理完用户的请求后,需要将指定的视图呈现给用户,即配置Action时,需要配置逻辑视图和物理视图资源之间的映射。
配置逻辑视图和物理视图之间的映射关系使用<result>标签,每个<result>标签定义逻辑视图和物理视图之间之间的一次映射,关于<result>标签,下篇文章会详细介绍。
2.动态方法调用
动态方法调用DMI(Dynamic Method Invocation),指请求一个Action中的不同处理逻辑方法。
语法如下:
actionName!methodName
其中:
- actionName是Action的名字,即<action>标签name属性的值。
- methodName是Action对应的实现类中的方法名。
看看下面的代码
@SuppressWarnings("serial")
public class ProductAction extends ActionSupport {
private int productId;
public ProductAction() {}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
/**
*编辑商品
*/
public String edit() {
System.out.println("编辑商品");
// 一些其他的业务逻辑代码
return "edit";
}
public String del() {
System.out.println("删除商品");
// 一些其他的业务逻辑代码
return "del";
}
}
上面的类是一个商品类继承了ActionSupport 类,有一个属性productId,以及两个方法。没有execute方法。
在struts.xml中进行配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 处于开发阶段,可以进行调试 -->
<constant name="struts.devMode" value="true"></constant>
<!-- 开启动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<package name="default" namespace="/" extends="struts-default">
<action name="product" class="com.codeliu.action.ProductAction">
<result name="edit">/edit.jsp</result>
<result name="del">/del.jsp</result>
</action>
</package>
</struts>
记得要开启动态方法调用,默认是不开启的。
再看product.jsp
<body>
<table border="1">
<tr>
<th>商品id</th>
<th>商品名称</th>
<th>操作</th>
</tr>
<tr>
<td>1001</td>
<td>apple</td>
<td>
<a href="product!edit?productId=1001">编辑</a>
<a href="product!del?productId=1001">删除</a>
</td>
</tr>
<tr>
<td>1002</td>
<td>banana</td>
<td>
<a href="product!edit?productId=1002">编辑</a>
<a href="product!del?productId=1002">删除</a>
</td>
</tr>
</table>
</body>
上面的超链接product!edit?productId=1002使用的就是动态方法调用,表示请求名为product的Action实现类的edit方法,传递了一个id。
下面分别是edit.jsp和del.jsp
<body>
${param.productId}商品编辑
</body>
<body>
${param.productId}删除成功
</body>
我们启动tomcat后,点击编辑,结果如下
18.png19.png
3.使用method属性及通配符
除了上面的动态方法调用之外,还有其他的处理方法。
<action>标签还有一个属性method,通过指定该属性的值,可以让Action调用指定的方法,而不是execute方法。
(1)利用method属性将上面的一个Action分解成两个
<action name="editproduct" class="com.codeliu.action.ProductAction" method="edit">
<result name="edit">/edit.jsp</result>
</action>
<action name="delproduct" class="com.codeliu.action.ProductAction" method="del">
<result name="del">/del.jsp</result>
</action>
这样在product.jsp中,<a>标签的href属性就改成下面这样
<a href="editproduct?productId=1001">编辑</a>
<a href="delproduct?productId=1001">删除</a>
运行之后结果还是和上面一样。
但这方法有点不好,因为我一个方法就得配一个Action,通常我们一个类里就有好多方法,这样配还不累死啊。
(2)利用通配符
先看下面的代码
<action name="*product" class="com.codeliu.action.ProductAction" method="{1}">
<result name="edit">/edit.jsp</result>
<result name="del">/del.jsp</result>
</action>
主要说一下这个method的值,{1}就表示name属性中第一个通配符*,以此类推。
这时product.jsp中的链接不用修改,和上面的一样。(这个通过看name属性的值就可以了)。访问结果还是如上。
我们还可以在class属性和method属性中都使用通配符,看下面的代码
<action name="*_*" class="com.codeliu.action.{1}Action" method="{2}">
<result name="edit">/edit.jsp</result>
<result name="del">/del.jsp</result>
</action>
含义还是和上面一个{1}表示第一个通配符,{2}表示第二个通配符。
这个时候我们请求Action的URL就得跟着来变,product.jsp中的超链接改成如下
<a href="Product_edit?productId=1001">编辑</a>
<a href="Product_del?productId=1001">删除</a>
记得这里P是大写的,因为它匹配类名。
网友评论