Action类是用户请求和业务逻辑之间的桥梁,每个Action充当客户的一项业务代理。在RequestProcessor类预处理请求时,在创建了Action的实例后,就调用自身的processActionPerform()方法,该方法在调用Action类的execute()。
Action的excute()方法调用模型的业务方法,完成用户请求,然后根据执行结果把请求转发给其他合适的WEB组件。
一、Action类缓存
struts应用的生命周期中RequestProcessor只保证一个Action实例,所有的客户请求都共享这个实例.所有请求可以同时执行它的excute()方法。RequestProcessor类包含一个HashMap,作为存放所有Action实例的缓存。每个Action实例在缓存中存放的key为Action类名。在RequestProcessor类的processActionCreate()方法中,首先检查在HashMap中是否存在Action实例,如果有直接使用,否则创建一个新的。创建Action实力的代码位于同步代码块中,以保证只有一个线程创建Action实例,然后放在HashMap中。供其他线程使用。
如下代码
protected Action processActionCreate(HttpServletRequest request,
HttpServletResponse response,
ActionMapping mapping)
throws IOException {
// Acquire the Action instance we will be using (if there is one)
String className = mapping.getType();
if (log.isDebugEnabled()) {
log.debug(" Looking for Action instance for class " + className);
}
// :TODO: If there were a mapping property indicating whether
// an Action were a singleton or not ([true]),
// could we just instantiate and return a new instance here?
Action instance = null;
synchronized (actions) {
// Return any existing Action instance of this class
instance = (Action) actions.get(className);
if (instance != null) {
if (log.isTraceEnabled()) {
log.trace(" Returning existing Action instance");
}
return (instance);
}
// Create and return a new Action instance
if (log.isTraceEnabled()) {
log.trace(" Creating new Action instance");
}
try {
instance = (Action) RequestUtils.applicationInstance(className);
// :TODO: Maybe we should propagate this exception
// instead of returning null.
} catch (Exception e) {
log.error(
getInternal().getMessage("actionCreate", mapping.getPath()),
e);
response.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
getInternal().getMessage("actionCreate", mapping.getPath()));
return (null);
}
instance.setServlet(this.servlet);
actions.put(className, instance);
}
return (instance);
}
二.创建支持多线程的Action
1.什么是线程安全的代码
在多线程环境下能正确执行的代码就是线程安全的。
安全的意思是能正确执行,否则后果是程序执行错误,可能出现各种异常情况。
2.如何编写线程安全的代码
很多书籍里都详细讲解了如何这方面的问题,他们主要讲解的是如何同步线程对共享资源的使用的问题。主要是对synchronized关键字的各种用法,以及锁的概念。
Java1.5中也提供了如读写锁这类的工具类。这些都需要较高的技巧,而且相对难于调试。
但是,线程同步是不得以的方法,是比较复杂的,而且会带来性能的损失。等效的代码中,不需要同步在编写容易度和性能上会更好些。
我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下:
1)常量始终是线程安全的,因为只存在读操作。
2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。
3)最重要的是:局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。
Servlet是在多线程环境下的。即可能有多个请求发给一个servelt实例,每个请求是一个线程。 struts下的action也类似,同样在多线程环境下,你也必须编写线程安全的Action类。
保证线程安全的原则就是仅仅使用局部变量,谨慎使用实例变量(拥有状态的实例,尤其是拥有业务对象状态的实例). 如果要用到那些有状态的实例,唯一和最好的办法是在Action类中,仅仅在Action类的execute()方法中使用局部变量,对于每个调用execute()方法的线程,JVM会在每个线程的堆栈中创建局部变量,因此每个线程拥有独立的局部变量,不会被其他线程共享.当线程执行完execute()方法后,它的局部变量就会被销毁.
如果Action类的实例变量是必须的话,需要采用JAVA同步机制(synchronized)对访问共享资源的代码块进行同步
三、Struts的几种Action
Struts提供了一些现成的Action类,直接使用可以大大节省时间,如下
ForwardAction
可以转发到其他web组件,仅仅提供一个转发功能,不作处理。
IncludeAction
包含其他web组件。
DiapatchAction
通常一个Action只完成一个操作,用这个Action可以完成一组相关的操作。
LookupDispatchAction
他是DiapatchAction的子类,也可以定义多个方法,但主要用于一个表单里有多个按钮,而这些按钮又有一个共同的名字的场合。
SwitchAction
用于子模块之间的切换。
四.ActionForward类
Action类的excute()方法返回一个ActionForward对象,它代表了web资源的逻辑抽象,这里的web资源可以是jsp页面、Java servlet、或Action。
从excute返回ActionForward可以有两种方法。
1) 动态创建一个ActionForward实例
return new ActionForward(”Failure”,”login.jsp”,true);
2) 调用ActionMappin实例的findForward方法
这个方法先从action级别找,然后在<global-forwards />级别找
return mapping.findForward(“Failure”);
分享到:
相关推荐
本教程将基于提供的"Strust1框架搭建完整代码"进行详解,帮助你理解和掌握Struts1的基础知识。 1. **Struts1简介** Struts1是早期Web开发中的重要框架,它简化了Java Servlet和JSP的开发,通过定义Action类和配置...
1. **ActionServlet组件**: ActionServlet是Struts1框架的中心控制器。它接收HTTP请求,通过doGet或doPost方法处理这些请求,并调用RequestProcessor进行进一步的处理。开发者可以通过扩展ActionServlet类来实现...
- **Action类**:Struts2的核心组件,负责处理用户的请求,执行业务逻辑,并返回结果。 - **Validation框架**:在Action执行前,对用户提交的数据进行验证,防止无效或非法数据进入系统。 - **Validation.xml**:...
- 保持Action类和视图的分离,尽量将业务逻辑放在Action中,而视图负责展示数据。 - 使用主题和模板来统一应用的UI风格。 - 验证用户输入,避免提交无效或重复的选项。 9. **实战示例** 可参考博客链接...
Struts框架由一系列的类、辅助类和定制的JSP标签库组成,如ActionServlet、Action和ActionForm等,开发者可以利用这些预定义的组件快速开发出功能完整的Web应用。 (5)框架的三层结构 - 接口层:定义了框架的公共...
### Struts2.0 学习资料核心知识点详解 #### 一、Struts2简介与特点 Struts2是基于Struts1发展而来的一个MVC(Model-View-Controller)框架,它继承了Struts1的优点,并在此基础上进行了大量的改进和优化。Struts2...
1. Action:Action是处理用户请求的核心组件,负责接收请求并调用业务逻辑。每个Action对应一个特定的表单提交或URL路径。 2. ActionForm:ActionForm对象用于封装HTTP请求参数,通常与JSP表单中的输入字段相对应。...
Struts框架的主要组件包括Action、ActionForm、ActionServlet、Struts配置文件(struts-config.xml)和JSP视图。Action负责处理用户请求,ActionForm用于封装表单数据,ActionServlet是Struts的核心,它作为Servlet...
3. **拦截器**:拦截器是Struts 2的核心组件,它们在Action调用前后执行,实现事务管理、日志记录、性能监控等跨切面关注点。 4. **OGNL(Object-Graph Navigation Language)**:Struts 2使用OGNL作为默认表达式...
这个案例"struts014"可能包含了实现上述功能的所有必要文件,如Action类、配置文件、JSP页面和JavaScript代码。 总之,理解并掌握Struts2的异步调用机制有助于开发出更高效、交互性更强的Web应用。通过实践案例...
《基于Spring+Struts+Ibatis的jPetStore实战详解》 jPetStore是一个经典的开源项目,它展示了如何使用Spring、Struts和Ibatis等技术构建一个完整的MVC(Model-View-Controller)架构的Web应用程序。这个项目是Java...
- `<action-mappings>`:定义了与用户请求相对应的动作,如`<action>`元素中的`path="/login"`对应着登录操作。 - `<message-resources>`:用于加载资源文件,这里指定了一个名为`Chinese`的资源文件,可能包含...
3. 如果数据满足业务逻辑的要求,Validator Framework 将数据传递给 Action 类,以便进行进一步的处理。 4. 如果数据不满足业务逻辑的要求,Validator Framework 将错误信息返回给用户,以便用户进行修改。 Struts2...
开发者可以利用Struts的Action类定义业务逻辑,Interceptor拦截器进行预处理或后处理,Tiles组件来组织和重用页面布局,使得整个系统的架构清晰且易于维护。 Oracle与Struts的集成,是大唐任务管理系统高效运作的...
3. **创建类与包**:根据项目需求,创建各种业务逻辑类(如Action类)、DAO(Data Access Object)类以及实体类等。一般按照Struts+Hibernate架构设计,会有`action`包、`dao`包、`entity`包等,遵循反域名命名规则...
**mvc模式详解** MVC(Model-View-Controller)是一种广泛应用的软件设计模式,尤其在Web开发领域。这种模式将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。通过分离关注点,MVC...
Struts2通过Action、Result和Interceptor等组件,实现了请求的处理和视图的渲染,使得开发者可以更加专注于业务逻辑的实现,而不是底层的细节。 在高校宿舍管理系统中,Struts2起到了关键作用。系统管理员可以通过...