Struts 2 简明教程

Struts 2 - Validations Framework

在本章中,我们将更深入地了解 Struts 验证框架。在 Struts 核心,我们有验证框架,它帮助应用程序运行规则,以便在执行操作方法之前执行验证。

In this chapter, we shall look deeper into Struts validation framework. At the Struts core, we have the validation framework that assists the application to run the rules to perform validation before the action method is executed.

客户端侧验证通常使用 Javascript 实现。但是,不应该只依赖于客户端验证。最佳实践表明,验证应该在应用程序框架的所有级别引入。现在让我们来看看向 Struts 项目添加验证的两种方法。

Client side validation is usually achieved using Javascript. However, one should not rely upon client side validation alone. The best practices suggest that the validation should be introduced at all levels of your application framework. Now let us look at two ways of adding validation to our Struts project.

在这里,我们取一个 Employee 的示例,它的名称和年龄应该使用一个简单页面捕获,并且我们对这两个验证进行设置,以确保用户始终输入名称和年龄,且该年龄应在 28 到 65 之间。

Here, we will take an example of an Employee whose name and age should be captured using a simple page, and we will put these two validations to make sure that the user always enters a name and age which should be in a range between 28 and 65.

让我们从示例的主要 JSP 页面开始。

Let us start with the main JSP page of the example.

Create Main Page

让我们编写主页面 JSP 文件 index.jsp ,它将用于收集上述与员工相关的信息。

Let us write main page JSP file index.jsp, which will be used to collect Employee related information mentioned above.

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <title>Employee Form</title>
   </head>

   <body>
      <s:form action = "empinfo" method = "post">
         <s:textfield name = "name" label = "Name" size = "20" />
         <s:textfield name = "age" label = "Age" size = "20" />
         <s:submit name = "submit" label = "Submit" align="center" />
      </s:form>
   </body>
</html>

index.jsp 利用 Struts 标记,我们尚未介绍,但我们在与标记相关的章节中将会学习。但就目前而言,我们假设 s:textfield 标记打印了一个输入域,并且 s:submit 打印了一个提交按钮。我们对每个标记都使用了 label 属性,从而为每个标记创建了标签。

The index.jsp makes use of Struts tag, which we have not covered yet, but we will study them in tags related chapters. But for now, just assume that the s:textfield tag prints a input field, and the s:submit prints a submit button. We have used label property for each tag which creates label for each tag.

Create Views

我们将使用 JSP 文件 success.jsp,它将在定义的动作返回 SUCESS 时被调用。

We will use JSP file success.jsp which will be invoked in case defined action returns SUCCESS.

<%@ page language = "java" contentType = "text/html; charset = ISO-8859-1"
   pageEncoding = "ISO-8859-1"%>
<%@ taglib prefix = "s" uri = "/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
   <head>
      <title>Success</title>
   </head>

   <body>
      Employee Information is captured successfully.
   </body>
</html>

Create Action

因此,让我们定义一个小型动作类 Employee ,然后添加一个名为 validate() 的方法,如下所示 Employee.java 文件。确保你的操作类扩展 ActionSupport 类,否则你的验证方法将不会被执行。

So let us define a small action class Employee, and then add a method called validate() as shown below in Employee.java file. Make sure that your action class extends the ActionSupport class, otherwise your validate method will not be executed.

package com.tutorialspoint.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class Employee extends ActionSupport {
   private String name;
   private int age;

   public String execute() {
       return SUCCESS;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }

   public void validate() {
      if (name == null || name.trim().equals("")) {
         addFieldError("name","The name is required");
      }

      if (age < 28 || age > 65) {
         addFieldError("age","Age must be in between 28 and 65");
      }
   }
}

如上面的示例所示,验证方法检查“名称”字段是否具有值。如果没有提供值,我们添加一个带有自定义错误消息的“名称”字段的错误域。其次,我们检查为“年龄”字段输入的值是否介于 28 和 65 之间,如果不满足此条件,我们在已验证字段之上添加一个错误。

As shown in the above example, the validation method checks whether the 'Name' field has a value or not. If no value has been supplied, we add a field error for the 'Name' field with a custom error message. Secondly, we check if entered value for 'Age' field is in between 28 and 65 or not, if this condition does not meet we add an error above the validated field.

Configuration Files

最后,让我们将所有内容组合在一起,使用 struts.xml 配置文件,如下所示 -

Finally, let us put everything together using the struts.xml configuration file as follows −

<?xml version = "1.0" Encoding = "UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name = "struts.devMode" value = "true" />
   <package name = "helloworld" extends = "struts-default">

      <action name = "empinfo"
         class = "com.tutorialspoint.struts2.Employee"
         method = "execute">
         <result name = "input">/index.jsp</result>
         <result name = "success">/success.jsp</result>
      </action>

   </package>
</struts>

以下是 web.xml 文件的内容:

Following is the content of web.xml file −

<?xml version = "1.0" Encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xmlns = "http://java.sun.com/xml/ns/javaee"
   xmlns:web = "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id = "WebApp_ID" version = "3.0">

   <display-name>Struts 2</display-name>

   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>

   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

现在,右键单击项目名称并单击 Export > WAR File 以创建 War 文件。然后将此 WAR 部署在 Tomcat 的 webapps 目录中。最后,启动 Tomcat 服务器并尝试访问 URL http://localhost:8080/HelloWorldStruts2/index.jsp 。这将生成以下屏幕:

Now, right click on the project name and click Export > WAR File to create a War file. Then deploy this WAR in the Tomcat’s webapps directory. Finally, start Tomcat server and try to access URL http://localhost:8080/HelloWorldStruts2/index.jsp. This will produce the following screen −

helloworldstruts12

现在不要输入任何必需信息,只需点击 Submit 按钮即可。您将看到以下结果 -

Now do not enter any required information, just click on Submit button. You will see the following result −

helloworldstruts121

输入必需信息,但输入一个错误的 From 域,假设名称为“测试”,年龄为 30,最后点击 Submit 按钮。您将看到以下结果 -

Enter the required information but enter a wrong From field, let us say name as "test" and age as 30, and finally click on Submit button. You will see the following result −

helloworldstruts122

How this Validation Works?

当用户按下提交按钮时,Struts 2 将自动执行验证方法,如果该方法中列出的任何 “if” 语句为真,Struts 2 将调用其 addFieldError 方法。如果添加了任何错误,Struts 2 将不会继续调用执行方法。相反,Struts 2 框架将返回 input 作为调用动作的结果。

When the user presses the submit button, Struts 2 will automatically execute the validate method and if any of the “if” statements listed inside the method are true, Struts 2 will call its addFieldError method. If any errors have been added, then Struts 2 will not proceed to call the execute method. Rather the Struts 2 framework will return input as the result of calling the action.

因此,当验证失败并且 Struts 2 返回 input 时,Struts 2 框架将重新显示 index.jsp 文件。由于我们使用了 Struts 2 表单标记,Struts 2 会自动将错误信息添加到表单域之上。

Hence, when validation fails and Struts 2 returns input, the Struts 2 framework will redisplay the index.jsp file. Since, we used Struts 2 form tags, Struts 2 will automatically add the error messages just above the form filed.

这些错误消息是我们指定的 addFieldError 方法调用中指定的内容。addFieldError 方法有两个参数。第一,是错误适用的 form 域名称,第二,是在该表单域上方显示的错误消息。

These error messages are the ones we specified in the addFieldError method call. The addFieldError method takes two arguments. The first, is the form field name to which the error applies and the second, is the error message to display above that form field.

addFieldError("name","The name is required");

要处理 input 的返回值,我们需要在 struts.xml 中的操作节点中添加以下结果。

To handle the return value of input we need to add the following result to our action node in struts.xml.

<result name = "input">/index.jsp</result>

XML Based Validation

第二种验证方法是将 xml 文件放在动作类的旁边。基于 Struts2 XML 的验证提供更多的验证选项,如电子邮件验证、整数范围验证、表单验证域、表达式验证、regex 验证、必需验证、必需字符串验证、字符串长度验证等等。

The second method of doing validation is by placing an xml file next to the action class. Struts2 XML based validation provides more options of validation like email validation, integer range validation, form validation field, expression validation, regex validation, required validation, requiredstring validation, stringlength validation and etc.

xml 文件需要命名为 '[action-class]'-validation.xml 。因此,在我们的示例中,我们创建了一个名为 Employee-validation.xml 的文件,内容如下 -

The xml file needs to be named '[action-class]'-validation.xml. So, in our case we create a file called Employee-validation.xml with the following contents −

<!DOCTYPE validators PUBLIC
   "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
   "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
   <field name = "name">
      <field-validator type = "required">
         <message>
            The name is required.
         </message>
      </field-validator>
   </field>

   <field name = "age">
     <field-validator type = "int">
         <param name = "min">29</param>
         <param name = "max">64</param>
         <message>
            Age must be in between 28 and 65
         </message>
      </field-validator>
   </field>
</validators>

上述 XML 文件理想情况下将保存在你的 CLASSPATH 中,同时还有类文件。让我们使用以下 validate() 方法定义我们的 Employee 操作类 -

Above XML file would be kept in your CLASSPATH ideally along with class file. Let us have our Employee action class as follows without having validate() method −

package com.tutorialspoint.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class Employee extends ActionSupport{
   private String name;
   private int age;

   public String execute() {
       return SUCCESS;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getAge() {
       return age;
   }

   public void setAge(int age) {
       this.age = age;
   }
}

其余的设置将与之前的示例保持一致,现在如果你运行应用程序,它将产生与我们之前示例中接收相同的结果。

Rest of the setup will remain as it is i the previous example, now if you will run the application, it will produce same result what we received in previous example.

将 xml 文件用于存储配置的优点是,它允许将验证与应用程序代码分开。你可以让一个开发人员编写代码,让业务分析员创建验证 xml 文件。另一件需要注意的事情是默认可用的验证类型。

The advantage of having an xml file to store the configuration allows the separation of the validation from the application code. You could get a developer to write the code and a business analyst to create the validation xml files. Another thing to note is the validator types that are available by default.

在 Struts 中还附带了更多的验证器。常见的验证器包括日期验证器、正则验证器和字符串长度验证器。请查看以下链接了解更多详细信息 Struts - XML Based Validators

There are plenty more validators that come by default with Struts. Common validators include Date Validator, Regex validator and String Length validator. Check the following link for more detail Struts - XML Based Validators.