调用非execute方法
在前面有关Action的学习中,我们的Action中真正实现业务逻辑的只有execute方法,如果我们每个Action中都只有这么一个方法的话,那么当我们程序中需要的功能很多时,我们就不得不手动编写很多的Action类了,这显然是不合理的。前面我也说道了我们的Action类并不一定非得继承某个类或者实现某个接口,我们可以使用POJO来作为我们的Action,并且我们的Action中也并不一定非得要有execute方法,如果我们使用的不是execute方法,那么我们就需要在配置Action的是时候在action标签上使用method属性来指出我们需要使用的动作方法。
那么我们也可以在一个Action中编写多个用于实现业务逻辑的方法,他们分别执行不同的功能,但是做的工作又是有相似的地方。比如我们可以将所有与用户相关的处理操作都写在UserAction当中,那么这样我们就能够更好的组织我们的代码。同样,我们只需要在struts.xml中为我们的action标签指定我们要使用的method即可。
要实现在一个Action类中调用非execute方法有三种实现方式:
(1)使用method属性
package action;
import bean.User;
import com.opensymphony.xwork2.ActionSupport;
public class UserAction extends ActionSupport{
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String execute() throws Exception {
//仅用于显示信息输入页面
return INPUT;
}
//保存User
public String save(){
User user = new User();
user.setUserName(userName);
user.setPassword(password);
//将user的信息保存到数据库
//UserDao.save(user)
return SUCCESS;
}
}
这里我们还需要一个User实体类,其实就是一个简单的JavaBean即可。
package bean;
public class User {
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
然后在struts.xml中对我们的Action进行配置
<packagename="default"namespace="/"extends="struts-default">
<actionname="userAdd"class="action.UserAction">
<resultname="input">/input.jsp</result>
</action>
<actionname="userSave"class="action.UserAction"method="save">
<resultname="success">/success.jsp</result>
</action>
</package>
Input.jsp
<formaction="userSave.action"method="post">
username : <inputtype="text"name="userName"/><br/>
password :<inputtype="password"name="password"><br/>
<inputtype="submit"value="submit"/>
</form>
success.jsp
<body>
hello ${userName }<br/>
your password is ${password }
</body>
我们在浏览器中测试一下:
我们直接在浏览器中访问userAdd.action,可以看到显示了信息输入页面
提交之后正确的显示除了success结果页面,说明我们的配置没有问题。
(2)使用通配符
除了使用上面说到的方法外,我们也可以不用在struts.xml中对Action中的每一个动作方法都进行配置,我们可以之配置一个,在这个actin中使用通配符来指定将要执行哪个方法。
<packagename="default"namespace="/"extends="struts-default">
<actionname="*User"class="action.UserAction"method="{1}">
<resultname="input">/input.jsp</result>
<resultname="success">success.jsp</result>
</action>
</package>
在UserAction中增加一个add方法,直接返回”input”,将input.jsp中form的action属性修改为”saveUser.action”。我们在浏览器中测试一下:
直接访问addUser.action,浏览器将会显示信息输入页面,说明调用了UserAction中的add方法:
页面提交到saveUser.action,调用了UserAction的save方法并呈现success结果页面.
注:通配符的方式也可以应用在result标签上。
(3)动态方法调用
除了上面介绍的方法,struts2中还有一种实现方法——动态方法调用。使用动态方法调用的格式为 action!method即使用”!”来连接我们配置的action和要执行的方法,使用这种方式我们不需要为acttion标签指定method属性。
<packagename="default"namespace="/"extends="struts-default">
<actionname="user"class="action.UserAction">
<resultname="input">/input.jsp</result>
<resultname="success">success.jsp</result>
</action>
</package>
然后我们要对input.jsp做一些修改,将form的action属性修改为”user!save”:
<formaction="user!save"method="post">
username : <inputype="text"name="userName"/><br/>
password :<inputtype="password"name="password"><br/>
<inputtype="submit"value="submit"/>
</form>
修改完成之后我们在浏览器中直接访问http://localhost/action/user!add
Input.jsp页面被呈现,说明UserAction的add方法被调用。
提交到user!save后success.jsp被呈现,说明UserAction的save方法被调用。
注意:对于使用通配符的方法来说,Struts2会认为我们将这些匹配到的方法就像是硬编码在struts.xml中一样,因此我们可以为这些进行匹配的action做一些其他处理,比如数据验证、本地消息和类型转换等。但是使用动态方法调用的方式,struts2知道我们调用了同一个action,只是执行了非execute方法,因此使用这种方式,这些动作方法都会共享一个Action的配置。所以从这个角度上来说,通配符的方式优于动态方法调用的方式。我们可以在struts.xml中通过配置来决定是否启用动态方法调用。
<constant name="struts.enable.DynamicMethodInvocation"value="false"/>
向对象传递数据
上面我们接触到的Action类都有一个共同的特性,那就是在action中使用属性来接收请求中的参数。我们定义了一个User类,专门由于表示User实体,但是在我们的Action类中我们都是手动的new一个User实体对象,然后使用set方法将接收到的值设置到User实体对象上,那么能不能直接使用User对象类接收请求中的参数,我们在动作方法中就可以直接操作User实体对象呢,答案是肯定的。实现的方式有两种。
(1)对象支持的javabean属性
我们已经知道Strtus2中的params拦截器会自动将请求中的数据转移到动作对象属性上。那么我们也可以直接使用实体对象作为动作对象的属性,这样Struts2就能自动将请求中的数据填充到我们的实体对象上。为了实现这个功能,我们需要在jsp页面中多做一些工作:
public class UserAction extends ActionSupport{
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String add() throws Exception {
//仅用于显示信息输入页面
return INPUT;
}
//保存User
public String save(){
//将user的信息保存到数据库
//UserDao.save(user)
return SUCCESS;
}
}
input.jsp
<formaction="user!save"method="post">
username : <inputtype="text"name="user.userName"/><br/>
password :<inputtype="password"name="user.password"><br/>
<inputtype="submit"value="submit"/>
</form>
Success.jsp
<body>
hello ${user.userName }<br/>
your password is ${user.userName }
</body>
运行浏览器进行测试,其结果和前面的测试相同,页面均能正常执行。
需要注意的是,我们的User对象并不需要我们手动实例化,Strtus2会自动实例化user,并且装配上面的属性。要实现这个功能,我们需要在结果视图中明确指出Action类中的实体(域)对象。下面学习的第二种方法我们的jsp页面可以不做任何改变,就和全部使用javabean一样。
(1)ModelDriven动作
要使用ModelDriven动作需要我们的动作实现com.opensymphony.xwork2.ModelDriven接口,在该接口中定义了一个getModel方法,我们要在Action类中实现这个方法,并在其中将我们的域对象返回。该接口支持泛型。需要注意的就是我们在返回域对象时要确保这个域对象已经实例化了。
public class UserAction extends ActionSupport implements ModelDriven<User> {
private User user = new User();
public String add() throws Exception {
// 仅用于显示信息输入页面
return INPUT;
}
public User getModel() {
return user;
}
// 保存User
public String save() {
// 将user的信息保存到数据库
// UserDao.save(user)
return SUCCESS;
}
}
要做的改变就是这些,结果视图里面和最初使用纯JavaBean实现时相同。
运行浏览器进行测试,可以看到得出的结果和前面相同。其实现原理是通过拦截器来调用,查看defaultStack拦截器栈,会看到其中有一个ModelDriven拦截器:
<interceptor-stackame="defaultStack">
<interceptor-refname="exception"/>
<interceptor-refname="alias"/>
<interceptor-refname="servletConfig"/>
<interceptor-refname="i18n"/>
<interceptor-refname="prepare"/>
<interceptor-refname="chain"/>
<interceptor-refname="scopedModelDriven"/>
<interceptor-refname="modelDriven"/>
<interceptor-refname="fileUpload"/>
<interceptor-refname="checkbox"/>
<interceptor-refname="multiselect"/>
<interceptor-refname="staticParams"/>
<interceptor-refname="actionMappingParams"/>
<interceptor-refname="params">
<paramname="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-refname="conversionError"/>
<interceptor-refname="validation">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-refname="workflow">
<paramname="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-refname="debugging"/>
</interceptor-stack>
这个拦截器在params拦截器之前,那么会在参数传递到到Action对象上之前将通过getModel获取到的域对象压入valueStack中,以供params拦截器将参数设置上去。查看文档可以知道modeldriven拦截器的实现类是com.opensymphony.xwork2.interceptor. ModelDrivenInterceptor
查看该拦截器的interceptor方法源码:
public Stringintercept(ActionInvocation invocation)throws Exception {
Object action = invocation.getAction();
if (actioninstanceof ModelDriven) {
ModelDriven modelDriven =(ModelDriven) action;
ValueStack stack =invocation.getStack();
Object model =modelDriven.getModel();
if (model !=null) {
stack.push(model);
}
if (refreshModelBeforeResult) {
invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven,model));
}
}
return invocation.invoke();
}
可以清晰看出这个拦截器对域对象所做的处理。从这里也可以看出,我们的域对象必须先实例化,才能产生效果。
总结:虽然使用实体对象保存请求数据看起来比较不错,不过在实际使用中还是直接使用javabean属性接收数据的方式比较多,这种方式操作简单,也比较容易控制。
分享到:
相关推荐
本笔记将全面总结Struts2的核心概念、主要功能以及实际开发中的应用。 一、Struts2概述 Struts2是Apache软件基金会下的一个开源项目,它继承了Struts1的优点并解决了其存在的问题,如性能和灵活性。Struts2的核心是...
根据给定的文件信息,以下是对Struts2学习笔记中涉及的关键知识点的详细解析: ### Struts2框架概览 #### MVC模式的理解与演进 Struts2是基于MVC(Model-View-Controller)模式设计的一种Java Web开发框架。在MVC...
本文将深入探讨Struts2的核心概念,包括Action、Result、配置文件、OGNL与ValueStack、Tags以及项目中的关键实践。 **一、Action** Action是Struts2中处理业务逻辑的核心组件,它是实现了`...
### Struts2 学习重点知识点总结 #### 一、Struts2 概念与架构 **1.1 Struts2 简介** - **定义**:Struts2 是 Apache 组织提供的一个基于 MVC 架构模式的开源 Web 应用框架。 - **核心**:Struts2 的核心其实是 ...
张龙圣思园的Struts2学习笔记,无疑为Java开发者提供了一份宝贵的参考资料,它可能涵盖了Struts2的基础概念、核心组件、配置方式以及实战技巧。 首先,让我们深入了解Struts2的核心特性。Struts2是MVC(Model-View-...
### Struts2学习笔记知识点概览 #### 一、环境搭建 **1.1 Struts2简介** - **Struts2概述**:Struts2是一个开源的MVC框架,它结合了Struts 1.x、WebWork和其他一些框架的优点。Struts2的主要目标是简化Web应用程序...
### Struts2学习笔记知识点详解 #### 一、Struts2框架的基本引入步骤 ##### 1. 导入Struts2相关Jar包 在引入Struts2框架时,首先需要将Struts2的相关Jar包导入到项目的类路径中。这些Jar包通常包括核心库以及其他...
### Struts2学习笔记之文件上传与Ajax开发 #### Struts2文件上传 **文件上传简介** 文件上传是Web应用中常见的功能之一,Struts2框架内置了对文件上传的支持,使得开发者能够轻松地实现这一功能。为了确保文件...
13. ** strut2四天笔记**:这份学习笔记可能涵盖了以上所有知识点,包括如何创建Action,配置struts.xml,使用OGNL表达式,处理异常,以及实践中的各种技巧和最佳实践。 在四天的学习过程中,你应该通过实践和理解...
本文将深入探讨Struts2的核心概念,包括Namespace、标签、Action以及它们在实际开发中的应用。 一、Namespace Namespace在Struts2中主要用于组织和隔离Action,它决定了Action的访问路径。默认情况下,Namespace为...
**五.Struts2的文件上传与下载** 1. **不使用Struts2进行上传**:可以使用Servlet API直接处理文件上传,但Struts2提供了更简便的API。 2. **使用Struts2进行上传**:Struts2提供`CommonsFileUploadInterceptor`来...
在Struts2中,学习笔记通常会涵盖以下几个关键概念: 1. **源代码查看和Javadoc**:开发者可以通过查看源代码来理解Struts2的工作原理,而Javadoc则提供了API文档,帮助理解类和方法的功能。 2. **包(Package)和...
这份"struts2学习笔记和源码"资源是学习这个框架的理想材料,特别适合初学者。 一、Struts2框架基础 Struts2是Apache软件基金会下的一个项目,它是Struts1的升级版,弥补了Struts1的一些不足,如动作映射和拦截器等...
### Struts2学习笔记2012 #### 一、建立一个Struts2工程 **步骤详解:** 1. **创建Web项目:** - 在MyEclipse中选择“File” > “New” > “Dynamic Web Project”,创建一个新的Web项目。 2. **解压并配置...