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

介绍

本篇教程中,将探索使用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页面。
这里写图片描述

一、准备工作及实例 3 1.解压struts-2.1.6-all.zip 3 2.六个基本包 3 3.初识struts2配置文件 4 (1).web.xml文件 4 (2).struts.xml文件 4 (3).struts.properties(参default.properties) 4 (4)struts-default.xml 4 (5)其它配置文件 4 4.让MyEclipse提示xml信息 4 5.如何使用alt+/提示 4 6.实例 4 7.开启struts2自带的开发模式常量 6 8.vo传参模式 7 9.ModerDriven传参模式(不建议采用) 7 10.为什么要使用struts2代替struts1.x 7 二、struts.xml配置及例程 7 1.配置文件的优先级 7 2.配置形式 8 3.package配置相关 8 4.分工合作include:指定多个配置文件 10 5.tomcat认证访问 10 6.初识拦截器 11 7.Action的method属性 12 8.使用ForwardAction实现页面屏蔽。 13 8.使用default-Action配置统一访问 14 小结Action 14 9.使用通配符 14 10.使用0配置:ZERO Annotation 15 11.Result配置详解 15 探讨type类型: 16 Type类型值 16 作用说明 16 对应类 16 chain 16 用来处理Action链 16 com.opensymphony.xwork2.ActionChainResult 16 dispatcher 16 用来转向页面,通常处理JSP 16 org.apache.struts2.dispatcher.ServletDispatcherResult 16 redirect 16 重定向到一个URL 16 org.apache.struts2.dispatcher.ServletRedirectResult 16 redirectAction 16 重定向到一个Action 16 org.apache.struts2.dispatcher.ServletActionRedirectResult 16 plainText 16 显示源文件内容,如文件源码 16 org.apache.struts2.dispatcher.PlainTextResult 16 freemarker 16 处理FreeMarker模板 16 org.apache.struts2.views.freemarker.FreemarkerResult 16 httpheader 16 控制特殊http行为的结果类型 16 org.apache.struts2.dispatcher.HttpHeaderResult 16 stream 16 向浏览器发送InputSream对象,通常用来处理文件下载,还可用于返回AJAX数据。 16 org.apache.struts2.dispatcher.StreamResult 16 velocity 16 处理Velocity模板 16 org.apache.struts2.dispatcher.VelocityResult 16 xslt 16 处理XML/XLST模板 16 org.apache.struts2.views.xslt.XSLTResult 16 全局result: 17 动态Result:了解 18 12.异常处理 18 三、在Action获取Scope对象 19 方式一、与Servlet解耦合的非IOC方式 20 方式二、与Servlet解耦合的IOC方式 21 方式三、与Servlet耦合的非IOC方式 21 方式四、与Servlet耦合的IOC方式 22 四、OGNL与ValueStack(VS) 22 1.值栈入门 22 2.OGNL入门 24 3.普通方法访问 24 4.静态方法访问 24 5.默认类Math的访问 24 6.调用普通类的构造方法 25 7.集合对象初步 25 8.集合对象进阶 25 9.N语法top语法 26 10.获取Stack Context的信息 26 11.总结$ # %的区别 27 12.总结OGNL[重点] 27 五、拦截器 28 1.概述strust2的拦截器 28 2.自定义拦截器 28 方式一,实现Interceptor接口。 28 方式二、继承AbstractInterceptor抽象类 29 方式三、继承MethodFilterInteceptor类 30 3.使用来MethodFilterInterceptor灵活拦截 32 4.使用默认的execAndWait拦截器 33 5.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值