Struts 2 配置Action

实现了Action处理类之后,就可以在struts.xml中配置该Action,从而让Struts 2框架知道哪个Action处理哪个请求,即建立用户请求和Action类之间的对应关系。

Action基本配置

Struts 2使用package包来组织Action,在struts.xml中通过使用package下的action元素来配置Action。在配置Action时,需要指定action元素的name和class属性。

  • name属性:指定Action的名字,即指明该Action所处理的请求的URL,例如,若name属性值为login,则请求该Action的URL是login.action
  • class属性:指定Action的实现类,该属性不是必须的,如果没有指定class属性的值,则默认使用ActionSupport类。

Action基本配置代码如下:

<package name="default" namespace="/" extends="struts-default">
    <action name="example" class="com.example.struts.action.expAction">
</package>

Action只是一个逻辑控制器,不直接对用户请求生成任何相应。因此,Action处理完用户请求后需要将指定的视图资源呈现给用户,即配置Action时,应该配置逻辑视图和物理视图资源之间的映射。

配置逻辑视图和物理视图之间的映射关系是通过<result>元素来定义的,每个<result>元素定义逻辑视图和物理视图之间的一个映射:

<package name="default" namespace="/" extends="struts-default">
    <action name="example" class="com.example.struts.action.expAction">
    <result name = "success">/success.jsp</result>
    <result name = "error">/error</result>
</package>
动态方法调用

有时一个Action内需要包含多个控制处理逻辑。例如,对于同一个表单,当用户通过不同的提交按钮进行提交时,系统需要使用Action的不同方法进行处理用户请求,此时就需要让Action中包含多个控制处理逻辑。

Struts 2框架允许一个Action中包含多个处理逻辑。在Struts 2中请求一个Action中的不同处理逻辑方法的方式成为DMI(Dynamic Method Invocation,动态方法调用),其请求格式如下:

(ActionName)!(methodName).action
  • ActionName是Action的名字,即struts.xml中配置的Action的name属性值;
  • methodName是Action实现类中处理逻辑的方法名。
动态方法调用示例
//访问product中的edit()方法
product!edit.action

productList.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>商品列表</title>
</head>
<body>
    <table border="1">
        <tr>
            <th>商品ID</th>
            <th>商品名称</th>
            <th>数量</th>
            <th colspan="2">操作</th>
        </tr>
        <tr>
            <td>1001</td>
            <td>小米手机</td>
            <td>128</td>
            <td><a href="product!edit.action?productId=1001">编辑</a></td>
            <td><a href="product!del.action?productId=1001">删除</a></td>
        </tr>
        <tr>
            <td>1002</td>
            <td>佳能相机</td>
            <td>100</td>
            <td><a href="product!edit.action?productId=1002">编辑</a></td>
            <td><a href="product!del.action?productId=1002">删除</a></td>
        </tr>
    </table>
</body>
</html>```

上述代码中,商品列表中的每个商品使用超链接进行编辑、删除操作。超链接中href属性值采用动态方法调用的方式进行链接请求,并将产品ID作为参数传递给Action。

ProductAction.java代码如下:

package com.qst.chapter03.action;

import com.opensymphony.xwork2.ActionSupport;

public class ProductAction extends ActionSupport {
    private int productId;

    public int getProductId() {
        return productId;
    }

    public void setProductId(int productId) {
        this.productId = productId;
    }

    // 编辑商品
    public String edit() {
        System.out.println("编辑商品" + productId);
        // ...省略一些编辑商品的业务
        return "edit";
    }

    // 删除商品
    public String del() {
        System.out.println("删除商品" + productId);
        // ...省略一些删除商品的业务
        return "del";
    }
}

上述代码创建了两个业务方法edit()和del()方法。当用户单击不同的链接时,系统将交给对应的方法处理。

接下来编写edit.jsp和del.jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<title>编辑商品</title>
</head>
<body>
    ${param.productId}商品编辑
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>

<title>删除商品</title>
</head>
<body>
    ${param.productId}商品删除成功!
</body>
</html>

在struts.xml中配置ProductAction代码如下所示:

<?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>
    <!-- 指定Struts2处于开发阶段,可以进行调试 -->
    <constant name="struts.devMode" value="true" />
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />

    <!-- Struts2的Action都必须配置在package里,此处使用默认package -->
    <package name="default" namespace="/" extends="struts-default">
        <!-- 定义一个名为user的Action,实现类为com.qst.chapter03.action.LoginAction -->
        <action name="product" class="com.qst.chapter03.action.ProductAction">
            <result name="edit">/edit.jsp</result>
            <result name="del">/del.jsp</result>
        </action>
    </package>

</struts>

上述配置文件配置了常量struts.enable.DynamicMethodInvocation的值为true,这样Struts 2才会开启动态方法调用,否则默认不会开启动态方法调用。

使用method属性及通配符

除了动态方法调用之外,Struts 2还提供了另一种处理方法,即将Action处理类定义成多个逻辑Action。此时,在配置<action>元素时,需要指定name、class和method属性。这样就可以让Action调用指定方法,而不是execute()方法来处理用户请求。

例如可以将ProductAction类定义成两个逻辑Action,即将该类中的edit()和del()方法映射成不同的Action,示例代码如下:

<action name="editproduct" class="com.qst.chapter03.action.ProductAction" method = "edit">
    <result name="edit">/edit.jsp</result>
</action>
<action name="delproduct" class="com.qst.chapter03.action.ProductAction" method = "del">
    <result name="del">/del.jsp</result>
</action>

上述代码定义了editproduct和delproduct两个逻辑Action,这两个Action对应的处理类都是ProductAction,但处理逻辑不同。分别对应的是edit()和del()方法。

上面的这种方式虽然能够实现,但两个定义绝大部分是相同的,带来冗余问题。Struts 2还提供了通配符“ * ”来解决这个问题。利用通配符在定义Action的name属性时使用模式字符串(即用“ * ”代表一个或多个任意字符串),接下来就可以在class、method属性以及<result>子元素中使用{N}的形式代表前面第N个星号“ * ”所匹配的子串。

* 通配符
<struts>
    <!-- 演示通配符的使用方法 -->
    <package name="product" extends="struts-default">
        <action name=" * product" class="com.qst.chapter03.action.ProductAction" method = "{1}">
            <result name="edit">/edit.jsp</result>
            <result name="del">/del.jsp</result>
        </action>
    </package>

</struts>

上述代码Action的name属性值为“ * product”,使用了通配符,此时定义的不是一个普通的Action,而是定义了一系列的逻辑Action,只要用户请求的URL符合“ * product.action”的模式,都可以通过ProductAction处理。此外,必须要指定method属性,method属性用于指定用户请求的方法。在method属性中使用表达式{1},代表该表达式就是name属性值中第一个“ * ”指代的值。通过上述配置规则可以达到与动态调用同样的运行效果。

此外Struts 2允许在class属性和method属性中同时使用表达式,例如:

<action name = " *_* " class = "com.qst.chapter03,action.{1}Action" method = " {2} ">
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,881评论 4 368
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,052评论 1 301
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,598评论 0 250
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,407评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,823评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,872评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,037评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,778评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,505评论 1 247
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,745评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,233评论 1 264
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,568评论 3 260
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,231评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,141评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,939评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,954评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,784评论 2 275

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,296评论 18 399
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,105评论 18 139
  • 概述 什么是Struts2的框架Struts2是Struts1的下一代产品,是在 struts1和WebWork的...
    inke阅读 2,182评论 0 50
  • 本文包括: 1、Struts 2 概述2、Struts 2 快速入门3、Struts 2 的执行流程4、配置 st...
    廖少少阅读 2,904评论 3 13
  • 表格 表格不仅用于装载数据,还可通过将其所在区域划分为行和列来实现网页的布局,标记为 。 表格标记 <table>...
    亮亮叔家的小笔笔阅读 313评论 0 1