Struts2 官方教程:处理表单(Processing Forms)

xiaoxiao2021-02-28  105

介绍

本篇教程中,将探索使用Struts2来做更多的表单提交信息处理。我们会讲解如何使用一个Java模型类来存储表单输入,以及如何构建Struts2 表单来配合模型类。 本篇教程中提供的代码可以添加到教程《Struts2动作类代码编写》的示例,活着也可以从github网站上下载完整示例。

表单和Java模型类

在本篇教程里,我们假设需要提供一个表单,让用户为了抽奖活动而提交用于注册的信息。我们的业务规则规定,用户必须提供他/她的姓、名、电子邮箱地址,以及年龄。 为了封装这些数据,我们讲使用一个简单的Java类,遵循基础的Java Bean规范(为每个实例区都提供公开的set/get方法)。如果你一路忠诚拜读系列教程至此,可以把下面这个类添加到《Struts2动作类代码编写》示例代码中的org.apache.struts.register.model包中。

Person.java

public class Person { private String firstName; private String lastName; private String email; private int age; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String toString() { return "First Name: " + getFirstName() + " Last Name: " + getLastName() + " Email: " + getEmail() + " Age: " + getAge() ; } }

注意上面这个类中的几个点。每个实例域(成员变量)都有一个公开的set/get方法。age属性是integer类型。定义了一个公开的toString()方法,返回一个代表对象状态的字符串。由于我们没有指定构造函数,Java回提供一个默认的构造函数,会用对应的null值设置所有的实例域。

表单结构

为了收集上述信息,我们将使用一个Struts2表单。构建这个表单时,需要引入的关键概念是:把每个表单域对应到Person类型对象的一个特定实例域。先整体地看一下表单,然后再讨论关键点。在src/main/webapp路径下创建名为register.jsp的页面。

register.jsp

<%@ taglib prefix="s" uri="/struts-tags" %> <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-i" /> </head> <body> <h3>完成填表即可注册抽奖!</h3> <s:form action="register"> <s:textfield name="personBean.firstName" label="名"/> <s:textfield name="personBean.lastName" label="姓"/> <s:textfield name="personBean.email" label="电子邮箱" /s> <s:textfield name="personBean.age" label="年龄" /> <s:submit/> </s:form> </body> </html>

由于我们使用Struts2标签,所以在页面最上方需要写Struts标签库的声明。 Struts2表单将会向一个名为register的动作提交,所以我们需要在struts.xml文件中定义这个动作。 注意四个Struts2的textfield标签。每个标签有一个name值,包括了一个Person类的属性(例如firstName)。这个name属性的值也有一个指向名为personBean对象的引用。这个对象的类型是Person。当我们创建控制这个表单提交行为的动作类,我们要在动作类中指定对象(见下方)。 完整的name值,personBean.firstName,引导Struts2使用这个textfield的输入值作为参数提供给personBean对象的setFirstName方法。这样如果用户在标签为“名”的textfield中输入了“Bruce”,那么personBean的firstName实例域,值就是“Bruce”。 注意我们对Person类的每个实例域都有了一个Struts2的textfield。记住,Person类的年龄属性是integer类型。所有表单域的输入值都是字符串。当调用personBean对象的setAge方法时,Struts2会自动地将用户为年龄表单域输入的字符串类型值(“25”)转换为25。

创建动作类来掌控表单提交

当用户点击上面表单的“提交”按钮,“register”这个动作以及表单数据会被发送到Struts2框架。我们需要一个动作类来处理这个表单。回顾一下前面的教程吧,自己编写的动作类应当继承Struts2的ActionSupport类。 这里是本示例所用的动作类。请将它打包到org.apache.struts.register.action。

Register.java Struts 2 动作类

package org.apache.struts.register.action; import com.opensymphony.xwork2.ActionSupport; import org.apache.struts.register.model.Person; public class Register extends ActionSupport{ private static final long serialVersionUID = 1L; private Person personBean; public String execute() throws Exception { //call Service class to store personBean's state in database return SUCCESS; } public Person getPersonBean() { return personBean; } public void setPersonBean(Person person) { personBean = person; } }

在Register类中,注意到我们已经声明了一个Person类型、名为personBean的属性(译者注:成员变量),并且Register对这个实例拥有公开的get和set方法。 Register类也重写了execute方法。execute是我们会在struts.xml中指定调用来响应register动作的方法。在这个例子中,execute方法只是返回了字符串常量SUCCESS(继承自ActionSupport类)。但在真正的应用里,在execute方法中我们应当调用其它类(服务实体)来执行表单的业务处理,例如存储用户的输入到数据仓库。 在Register动作类中声明的,Person类型的personBean这个实例,对应到我们在表单中name值为personBean的textfield。当表单被提交,Struts2框架将会检查动作类并且寻找名为personBean的实例;会使用Person类的默认构造函数创建这个实例。然后,对每个拥有name值为personBean.某某某(例如personBean.firstName)的表单域,将会为这个属性调用personBean的公开set方法,并且将表单域的值(即用户的输入)传递过去。这些都发生在execute方法执行之前。 当Struts2执行Register的execute方法,Register类的personBean实例的实例域(译者注:成员变量)现在拥有了对应自己这个实例的值,等于用户在对应的表单域里输入的值。 通过使用一个Java模型类来封装表单提供的数据,我们就不必在动作类(Register)中,为每个表单域都提供单独的属性(及公开的set/get方法们)。 【译者注:目前这里的“模型类”应该是指Person类。“封装对应表单域的属性和set/get方法”是一定要存在的;要么像先前示例那样在动作类中书写,要么像本例这样放在Person这个模型类里,让动作类不体现这些细节。】

在视图中添加结果

当execute方法返回了“SUCCESS”,我们希望为用户的注册显示一个简单的感谢页面。在src/main/webapp路径下添加thankyou.jsp。

thankyou.jsp

<%@ taglib prefix="s" uri="/struts-tags" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>Registration Successful</title> </head> <body> <h3>Thank you for registering for a prize.</h3> <p>Your registration information: <s:property value="personBean" /> </p> <p><a href="<s:url action='index' />" >Return to home page</a>.</p> </body> </html>

如果读者没想起来Struts2的property和url标签是如何工作的,回头看看《使用Struts2标签》教程。

在struts.xml中创建动作映射

为了指定表单提交页、Struts2动作类、以及success视图页面之间的关系,现在要在struts.xml中添加一个动作结点。将以下动作结点添加到struts.xml中,在hello动作之后、包封闭结点之前。

struts.xml中的action结点

<action name="register" class="org.apache.struts.register.action.Register" method="execute"> <result name="success">/thankyou.jsp</result> </action>

以上动作告诉Struts2,当register动作被提供来调用Register类的execute方法,如果方法返回了“success”这个结果,那么把thankyou.jsp这个页面返回给浏览器。 注意,咱并不需要告诉Struts2任何关于处理表单的过程。表单域输入值传输到personBean实例会自动地发生,因为我们遵循了“将表单域命名与personBean属性名一致”的规则(例如表单域中的lastName与personBean.lastName)。

创建到Register.jsp的链接

添加以下链接到index.jsp,这样用户就可以找到注册页面咯。

到register.jsp的链接

<p>请先<a href="register.jsp">注册</a>就能抽奖咯</p>

运行示例

若万事俱备,就可以运行这个应用,并且再浏览器中打开index.action。页面里应当有一个注册的链接。点击这个链接,应能看到注册页面。 填写表单,并且点击“提交”按钮。 应当能看到thankyou.jsp页面。

转载请注明原文地址: https://www.6miu.com/read-39082.html

最新回复(0)