Struts 2.x权威指南
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.8.1 继承ActionSupport

ActionSupport 类是一个工具类,它已经实现了 Action 接口。除此之外,它还实现了Validatable 接口,提供了数据校验功能。通过继承该 ActionSupport 类,可以简化 Struts 2 的Action开发。

在Validatable接口中定义了一个validate方法,重写该方法,如果校验表单输入域出现错误,则将错误添加到ActionSupport类的fieldErrors域中,然后通过OGNL表达式负责输出。

为了让Struts 2增加输入数据校验的功能,改写程序中的LoginAction,增加重写validate方法。修改后的LoginAction类代码如下。

程序清单:codes\02\2.8\validate1\WEB-INF\src\org\crazyit\struts2qs\action\LoginAction.java

// 继承ActionSupport来实现Action
public class LoginAction extends ActionSupport
{
    //下面是用于封装用户请求参数的两个属性
    private String username;
    private String password;
    // 省略username属性的getter和setter方法
    ...
    // 省略password属性的getter和setter方法
    ...
    // 处理用户请求的execute方法
    public String execute() throws Exception
    {
          // 当用户请求参数的username等于crazyit,密码请求参数为leegang时
          // 返回success字符串,否则返回error字符串
          if (getUsername().equals("crazyit")
                && getPassword().equals("leegang"))
          {
                // 通过ActionContext对象访问Web应用的HTTP Session
                ActionContext.getContext().getSession()
                    .put("user" , username);
                return SUCCESS;
          }
          else
          {
                return ERROR;
          }
    }
    // 完成输入校验需要重写的validate方法
    public void validate()
    {
          // 如果用户名为空,或者用户名为空字符串,则添加错误提示
          if (getUsername() == null ||
                getUsername().trim().equals(""))
          {
                // 添加表单校验错误提示
                addFieldError("username", "user.required");
          }
          // 当密码为空,或者密码为空字符串时,添加错误提示
          if (getPassword() == null ||
                getPassword().trim().equals(""))
          {
                addFieldError("password", "pass.required");
          }
    }
}

上面的Action类重写了validate方法,该方法会在执行系统的execute方法之前执行,如果执行该方法之后,Action类的fieldErrors中已经包含了数据校验错误,请求将被转发到input逻辑视图处。

为了在校验失败后能转入名为input的逻辑视图,必须在配置该Action时指定input属性。下面是修改后的login Action的配置片段。

程序清单:codes\02\2.8\validate1\WEB-INF\src\struts.xml

<!-- 定义login的Action,该Action的实现类为lee.LoginAction类 -->
<action name="login" class="lee.LoginAction">
    <!-- 定义处理结果和视图资源之间的映射关系 -->
    <!-- 定义input逻辑视图名,对应loginForm.jsp页面 -->
    <result name="input">/WEB-INF/content/loginForm.jsp</result>
    <result name="error">/WEB-INF/content/error.jsp</result>
    <result name="success">/WEB-INF/content/welcome.jsp</result>
</action>

对比上面的Action配置与前面的Action配置,我们发现该Action配置片段中增加了input逻辑视图的配置,该逻辑视图映射到loginForm.jsp页面。

前面已经提到:当用户提交请求时,在请求得到 execute 方法处理之前,先会被 validate方法处理,如果该方法处理结束后,Action的fieldErrors里的校验错误不为空,请求将被转发给input逻辑视图。如果不输入用户名、密码而直接提交表单,将看到如图2.13所示的界面。

看到这里也许读者觉得非常神奇:我们仅仅在 Action 中添加了数据校验错误,并未在表单页面上输出这些校验错误信息,但图2.13所示的界面已经输出了这些校验信息——这是因为Struts 2的标签,上面JSP页面的表单使用的并不是HTML表单,而是<s:form .../>标签和Struts 2表单控件标签,Struts 2的<s:form .../>和表单控件标签已经具备了输出校验提示的能力。

图2.13 输入校验的界面

注意

Struts 2的<s:form .../>和表单控件默认已经提供了输出校验错误的能力。

但上面的程序还存在一个问题:校验信息的国际化。查看上面的 Action 类代码发现:重写validate方法时,如果校验失败,校验错误的提示信息已经以硬编码方式写死了——这就失去了国际化的能力。

实际上,ActionSupport类已经提供了国际化信息的能力,它提供了一个getText(String key)方法,该方法用于从资源文件中获取国际化信息。为了让校验信息支持国际化,再次改写Action里的validate方法,改写后的validate方法代码如下。

程序清单:codes\02\2.8\validate1\WEB-INF\src\org\crazyit\struts2qs\action\LoginAction.java

// 完成输入校验需要重写的validate方法
public void validate()
{
    // 如果用户名为空,或者用户名为空字符串
    if (getUsername() == null ||
          getUsername().trim().equals(""))
    {
          // 添加校验错误提示,使用getText方法来使提示信息国际化
          addFieldError("username", getText("user.required"));
    }
    // 当密码为空,或者密码为空字符串时,添加表单校验错误
    if (getPassword() == null ||
          getPassword().trim().equals(""))
    {
          addFieldError("password", getText("pass.required"));
    }
}

在上面的validate方法中,添加校验错误提示时,并不是直接给出了错误提示字符串,而是调用了getText(key)方法来获取错误提示。因为在Action中,使用getText(key)方法获取了两个国际化提示:user.required和pass.required,因此应该在国际化资源文件中添加这两条提示信息。

提示:

ActionSupport 增加了让提示信息国际化的能力,ActionSupport 提供的getText(key)方法可以根据资源文件加载获得国际化提示信息。

此时,如果没有任何输入,直接提交登录表单,将看到如图2.14所示的界面。

图2.14 国际化数据校验的错误提示