Action的作用——传递数据
本章节我们会继续讨论Action,在这里您将了解到Action的基本作用和传递数据的做法。
Action的作用
在上个章节中我们了解到所谓的Action类大体上有3个作用:
完成所需的业务逻辑
提供数据传递的中介
确定要显示的页面
现在我们知道所谓的业务逻辑的完成是在Action方法中完成的,不过要提及到的是,我们以MVC的观念来看Action类的职位属于Controller(控制器),所以在Action方法中业务逻辑的完成应当是通过调用业务逻辑层来完成的,而不是将具体的业务逻辑实现在Action方法中,要不然问题就大了。
Action类的另外一个作用就是确定要显示的页面,确定要显示的方式是以返回一个字符串然后和struts.xml的配合来完成的【通常我把这个确定显示页面的字符串称为控制字符串】。上章节我们还了解到确定要返回的页面在struts.xml中用<result>元素来定义,<result>元素默认以type=”dispather”的形式来确定要返回到的页面。这里type 的值有多种,【您可以在Struts2的文档result-types.html,找到关于type值的说明】。所以说我们之前说的Action类的作用之3:确定要显示的页面,这一条就有点小看Struts2在这方面的作用了。为什么之前这么说就是让大家理解起来简单,要不然就有点难理解Struts2确定页面的方式,希望大家能够理解。
在本章节中我并不打算和大家讨论关于Action类处理业务逻辑的问题和确定“页面“的问题,当然后面我会说到的,至于为什么不一下把Action的作用说完,您慢慢就会了解到的。
传递数据
现在我们来看Action类传递数据的作用,首先来回想一下我们之前做过的HelloWorld实例程序。来想一下HelloWorld程序中数据的传递方式,我们在页面上单击一个超级连接,然后会请求相应的Action,在Action方法中我们放入了消息数据,然后在页面上使用了Struts2提供的取值标签来获得值。我们从过程上来看就是这样,不知您有没有注意到在Action类中有一个属性。这个属性就是Message类的一个实例,而且我们为这个属性设置了setter和getter方法。这样做的目的就是让这个属性拥有获得数据和被访问的能力。在要显示的页面上我们使用这个属性名然后加“ .“ 的方式访问到了Message类的属性。当然这里没有体现到能接受客户端的数据。OK,我们现在来做一个实例来看一看。
这个实例是这个样子的:我们在某个页面输入用户的基本信息,然后点击提交,在另外一个页面上显示我们提交的数据。这里要提醒大家一点,实例会涉及到一些Struts2标签的一些用法,您可能不太了解,别着急,后面我会详细说到。
Step 1:
首先我们来把Struts2安装好,然后new一个jsp页面来让用户输入相关数据,这里我们要提供一个表单,让用户输入用户名和年龄和电子邮件。这里我们要引用Struts2的标签来帮助我们实现这一功能。OK ,我们来看一下这个jsp页面:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Input User Message</title> </head> <body> <h2>Please input your Message.</h2> <s:form action="userAction"> <s:textfield name="name" label="Your name" /> <s:textfield name="age" label="Your age"/> <s:textfield name="email" label="Your email"/> <s:submit /> </s:form> </body> </html>
Step 2:
然后我们在new 一个jsp页面来显示上面用户的输入:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Show Book Message</title> </head> <body> <h2>Here is a book Message :</h2> Book name : <s:property value="name" /><br /> Price : <s:property value="price" /><br /> PublishingHouse : <s:property value="publishingHouse" /><br /> </body> </html>
Step 3:
现在我们要new 一个Action类来作为数据传递的纽带:
package com.lele.struts2.useAction.action;
public class UserAction {
private String name;
private int age;
private String email;
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 String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Step 4:
现在我们要把页面和Action关联起来,这里我就不贴代码了,大家自己动手写一下,可能会有意想不到的收获。
OK,我们的任务完成了,快来看一下:
单击提交按钮后:
做完这个小实例相信您对Action传递数据的作用会有所上升。当然这里我们是在Action类中直接定义了几个属性,有些时候我们为了业务的需要会把某个类的实例作为Action类的属性,这种方式应该怎样传递数据呢?您可以直接参考我们之前做过的“HelloWorld”实例。而且这种方式您不用关心对象的建立,Struts2会自动帮助您建立。
在页面的Struts2标签中使用“对象名.属性”的方式来引用数据。
ModelDriven接口
不过这样做有些时候不够“优雅”,因为我们在页面上,要设置数据或获得数据时总是在使用”.”的方式来获取或设置数据,这样有时候会有点导致页面有些“混乱”。有没有一种好的方式来解决它呢?
有,在Struts2中提供了这么一个接口:ModelDriven,在这个接口中止定义了一个方法:getModel,这样就能避免一些“混乱”。OK,我们马上来看一个实例:
我们要输入一个书籍的基本信息,然后再另一个页面上显示出来,仅此而已。
Step 1:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Input Book Message</title> </head> <body> <h2>Please input book Message here.</h2> <s:form action="bookAction"> <s:textfield name="name" label="Book name" /> <s:textfield name="price" label="Price"/> <s:textfield name="publishingHouse" label="Publishing house"/> <s:submit /> </s:form> </body> </html>
Step2 :
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Show User Message</title> </head> <body> <h2>Your Message :</h2> Name : <s:property value="name"/><br /> Age : <s:property value="age" /><br /> Email : <s:property value="email" /><br /> </body> </html>
Step 3:
package com.lele.struts2.useAction.model;
public class Book {
private String name;
private double price;
private String publishingHouse;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getPublishingHouse() {
return publishingHouse;
}
public void setPublishingHouse(String publishingHouse) {
this.publishingHouse = publishingHouse;
}
}
Step 4:
package com.lele.struts2.useAction.action;
import com.lele.struts2.useAction.model.Book;
import com.opensymphony.xwork2.ModelDriven;
public class BookAction implements ModelDriven<Book>{
private Book book;
public String execute() {
return "success";
}
@Override
public Book getModel() {
book = new Book();
return book;
}
}
Step 5:
现在我们又要使用struts.xml把页面和Action关联起来,这里我就不贴代码了。
OK ,大功告成,不过没什么好演示的,这里就不贴图了。
好了,本章节就到这里了,简单介绍了Action类的传递数据的作用。通常情况下我们可以把要传递的数据作为Action类的属性,并且提供getter和setter方法来让客户端访问和设置数据。当Action的属性由某个类的对象来充当时,而且要对其进行数据传递,这个时候第一种方法,就会暴露出某些缺点。然后我们使用了另外一种方式,让Action类实现一个接口ModelDriven的方式来解决这个“问题”。
我们可以看到实现ModelDriven接口的方式需要我们自己创建模型对象,而我们用setter和getter方法的方式却不需要。哪种方式更适合您,您自己做选择吧。
现在我们所做的是数据借助模型层(Model)或数据直接到控制层(Controller ,Action),数据是来自于页面,又到页面中去。现在假设某个数据在session对象中,在request对象中,能不能获取或设置到呢?下个章节我们将讨论在Action类中访问Servlet API的问题。
在我们所做的实例中存在着不少的问题,比如说数据类型的校验问题,比如说数据类型转化的问题,这些目前不能很好的处理,后面我会详细的说道这些问题的解决方法。现在您要做的是把当前我们所讨论的问题解决掉,然后试试Action属性有个List类型的或者是Map类型的怎样处理呢?数据能在页面中得到能在JavaScript脚本中得到吗?得到后怎样操作这些数据呢?得不到数据怎样让脚本代码得到数据呢?
OK,下个章节我们再见。