零基础学Struts
上QQ阅读APP看书,第一时间看更新

4.4 动态方法调用以及校验动态方法

Struts 2允许在一个Action中包含多个处理逻辑,从而通过调用Action中不同的方法来处理请求。同样对于每个处理逻辑,都可以提供相应的校验方法。下面介绍如何添加动态方法调用以及校验动态方法的使用。

4.4.1 动态方法调用

Struts 2允许在一个Action中包含多个处理逻辑。例如在同一个表单中,用户通过不同的按钮提交表单时,在Action中调用不同的方法来处理请求。

下面来看一个简单示例。首先新建如下的JSP页面。该页面同前面的用户注册页非常类似,不同的是增加了一个“删除”按钮,代码如下所示。

        <%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
        <%@ taglib prefix="s" uri="/struts-tags" %>
        <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
        <html>
          <head>
            <title>注册页面</title>
          </head>
          <body>
            <! -- 注册表单 -->
            <center>
            <h2>注册页面</h2>
            <s:form action="register">
                    <s:textfield name="username" label="用户名"></s:textfield>
                    <s:password name="password" label="密码"></s:password>
                    <s:password name="repassword" label="确认密码"></s:password>
                    <s:textfield name="age" label="年龄"></s:textfield>
                    <s:textfield name="birth" label="出生日期"></s:textfield>
                    <s:textfield name="email" label="邮箱地址"></s:textfield>
                    <s:submit value="注册"></s:submit>
                    <s:submit value="删除" action="register! deleteUser"></s:submit>
              </s:form>
              </center>
          </body>
        </html>

“删除”按钮中指定action属性值为register! deleteUser,表示将表单提交给配置名为regist的Action的deleteUser方法来处理。

下面再增加一个Action。该Action与前面的RegisterAction类似,只是添加deleteUser方法。在deleteUser方法中简单地添加一句语句打印到控制台上,方便查看运行结果,代码如下所示。

        package net.hncu.action;
        import java.util.Calendar;
        import java.util.Date;
        import java.util.regex.Pattern;
        import com.opensymphony.xwork2.ActionSupport;
        public class RegisterAction extends ActionSupport{
              private String username;
              private String password;
              private String repassword;
              private int age;
              private Date birth;
              private String email;
              public String getUsername() {
                    return username;
              }
              public void setUsername(String username) {
                    this.username = username;
              }
              public String getPassword() {
                    return password;
              }
              public void setPassword(String password) {
                    this.password = password;
              }
              public String getRepassword() {
                    return repassword;
              }
              public void setRepassword(String repassword) {
                    this.repassword = repassword;
              }
              public int getAge() {
                    return age;
              }
              public void setAge(int age) {
                    this.age = age;
              }
              public Date getBirth() {
                    return birth;
              }
              public void setBirth(Date birth) {
                    this.birth = birth;
              }
              public String getEmail() {
                    return email;
              }
              public void setEmail(String email) {
                    this.email = email;
              }
              public void validate() {
              }
              public String deleteUser() throws Exception {
                    System.out.println("delete method");
                    return SUCCESS;
              }
              public String execute() throws Exception {
                    System.out.println("execute method");
                    return SUCCESS;
              }
    }

接下来在“struts.xml”文件中配置该Action,代码如下所示。

    <struts>
          <package name="struts2" extends="struts-default">
                <! -- 定义registerAction,其实现类为net.hncu.action.RegisterAction-->
                <action name="register" class="net.hncu.action.RegisterAction">
                    <! -- 定义处理结果与视图资源之间的关系-->
                    <result name="success">/result.jsp</result>
                    <result name="input">/register.jsp</result>
                </action>
        </package>
      </struts>

运行用户注册页,如图4.18所示。该注册页中包含两个按钮,分别对应着不同的处理逻辑。

这里为了简单测试,并不输入任何的用户信息。直接单击“注册”按钮,在控制台将打印如下语句。

    execute method

这表示在Action中执行的是execute方法。如果单击“删除”按钮,在控制台将打印如下语句。

    delete method

这表示在Action中执行的是deleteUser方法。通过这种方式可以在一个Action中设置多个处理逻辑,并通过为表单元素指定不同action属性来提交给Action中不同的方法。

如果一个Action中包含多个处理逻辑,那是不是可以把所有的处理逻辑都放到一个Action中呢?其实不是这样的。一般来说,只有当两个Action中接受的用户参数相同时,才可以考虑将两个Action放到一个Action中,这样可以不用重新创建Action,因此可以节省时间和资源。

4.4.2 为action元素指定method属性

上次通过在“删除”按钮中指定其action属性值为register! deleteUser,从而将表单提交给配置名为regist的Action的deleteUser方法来处理。发现指定action属性值为register! deleteUser这样的方式比较麻烦。如果能够像“注册”按钮那样直接提交给一个register应该会比较好一点。

图4.18 用户注册页

这个时候要借助于“struts.xml”配置文件了。在<action>元素中指定action的method属性,则可以让Action类调用指定的方法,代码如下所示。

        <action name="deleteUser" class="net.hncu.action.RegisterAction" method=" deleteUser ">
        </action>

通过这种方法,就好比将一个Action定义成了多个逻辑上的Action, Action类的每个处理方法被映射成一个逻辑Action。

现在添加一个<action>元素,配置其name属性为“deleteUser”,实现类为“net.hncu. action. RegisterAction”, method属性为“deleteUser”,代码如下所示。

        <struts>
              <package name="struts2" extends="struts-default">
                  <! -- 定义registerActin,其实现类为net.hncu.action.RegisterAction-->
                  <action name="register" class="net.hncu.action.RegisterAction">
                        <! -- 定义处理结果与视图资源之间的关系-->
                        <result name="success">/result.jsp</result>
                        <result name="input">/register.jsp</result>
                  </action>
                  <! -- 定义deleteUserAction,其实现类为net.hncu.action.RegisterAction,采用
                  deleteUser方法来处理-->
                  <action name="deleteUser" class="net.hncu.action.RegisterAction" method="deleteUser">
                          <result name="success">/result.jsp</result>
                          <result name="input">/register.jsp</result>
                    </action>
            </package>
          </struts>

这时只要将用户注册页的“删除”按钮中对应的method属性值修改为deleteUser就行了。

那是不是说如果没有指定method属性值,就会调用execute方法呢?答案是肯定的,如果配置了method属性,那么在Action中将调用该method指定的方法。如果没有配置method属性,那么就调用默认的execute()方法。

4.4.3 校验动态方法

前面介绍的在一个Action中包含多个处理逻辑,不同处理逻辑对应不同的方法。那如何定义输入校验来校验这些处理逻辑呢?

下面来看一个简单示例,首先在上一示例的Action中添加一个validate()方法,该方法将在控制台上简单地打印一句话,代码如下所示。

        public void validate() {
            System.out.println("validate method");
        }

这里为了简单测试,并不输入任何的用户信息。直接单击“注册”按钮,在控制台中将打印如下语句。

        validate method
        execute method

从控制台打印的语句可以看出,在Action中首先执行了validate()校验方法,然后再执行execute()处理逻辑方法。如果单击“删除”按钮,在控制台中将打印如下语句。

        validate method
        delete method

从控制台打印的语句可以看出,在Action中首先执行了validate()校验方法,然后再执行deleteUser()处理逻辑方法。从上可以看出,不管执行调用哪个处理逻辑,都会执行validate方法。

Sturts 2允许为执行的处理逻辑提供校验方法。通过增加一个validate×××()方法来完成,其中×××对应处理逻辑方法名。下面来为deleteUser()方法添加校验方法,该方法也是在控制台简单的打印一句话,代码如下所示。

        public void validateDeleteUser(){
              System.out.println("validateDeleteUser method");
        }

这时直接单击“删除”按钮,在控制台中将打印如下语句。

        validateDeleteUser method
        validate method
        delete method

从控制台打印的语句可以看出,在Action中首先执行了对应deleteUser()方法的校验方法,然后再执行了validate()方法,最后再执行处理逻辑deleteUser()方法。

因为不管用户向Action的哪个处理方法发送请求,Action内的validate()方法都会被调用。所以可以将对应处理逻辑的校验代码放到validate×××()方法中,而validate()方法中可以不用添加任何的校验代码。同样可以添加validateExecute()方法来校验默认处理逻辑方法,代码如下所示。

        public void validateExecute(){
              System.out.println("validateExecute method");
        }

这时直接单击“注册”按钮,在控制台中将打印如下语句。

        validateExecute method
        validate method
        execute method

为了不使校验代码出现混乱,可以将处理逻辑中相同的校验代码放到validate()方法中。不同的校验代码则放到对应的validate×××()方法中。

4.4.4 Struts 2输入校验流程

为了能够更加了解输入校验的流程,下面来看输入校验的程序流程图,如图4.19所示。

图4.19 Sturts 2输入校验流程图

(1)类型转化器负责将用户提交的参数进行类型转换,并将类型转换后的值赋值到Action的相应属性中。

(2)如果类型转换出错的话,Struts 2将自动调用conversionError拦截器将错误提示信息保存到fieldError中。

(3)不管类型转换失败与否都会调用validate×××()方法。

(4)调用Action中的validate()方法。

(5)自动判断fieldError中是否为空,如果为空则表示有错误提示信息。页面跳转到input对应的逻辑视图。如果不为空则表示没有错误提示信息,执行Action中的处理逻辑方法(如execute方法)并进行业务逻辑处理。处理完成后根据处理结果返回值跳转到相应的视图资源。