Struts 简单分析
一. ActionServlet
Struts的核心控制器,web.xml的配置,使它可以截获所有 *.do 的请求
<!-- Standard Action Servlet Configuration -->
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
ActionServlet就是一个普通的servlet,继承了HttpServlet,覆写了doPost和doGet方法。
doPost()或doGet()均调用Process(),Process()内部主要为:
RequestProcessor processor = getProcessorForModule(config);
processor.process(request, response);
RequestProcessor则是struts最核心的类,可以看出所有的请求最终都由此类处理。
RequestProcessor的process(request, response)方法详细处理:
1.截取URL
// Identify the path component we will use to select a mapping
String path = processPath(request, response);
截取URL,若为null,直接返回。
2.根据path,获取匹配的ActionMapping,每个Action对应一个ActionMapping
a.// Identify the mapping for this request
ActionMapping mapping = processMapping(request, response, path);
b.// Is there a mapping for this path?
ActionMapping mapping = (ActionMapping) moduleConfig.findActionConfig(path);
moduleConfig是ModuleConfig的对象,ModuleConfig是一个接口,定义了对struts-config.xml文件的操作,具体由ModuleConfigImpl实现,对findActionConfig()方法的实现为:
ActionConfig config = (ActionConfig) actionConfigs.get(path);
actionConfigs是一个HashMap。当ActionServlet第一次实例化得时候,就读取struts-config.xml,所有的配置都读入到HsahMap,并保存到ServletContext的范围内,HashMap的“键值对”中key为path,value为ActionMapping 的实例。
ActionMapping继承ActionConfig,则根据path 得到对应Action的配置信息。
3.处理ActionForm
a.// Process any ActionForm bean related to this request
ActionForm form = processActionForm(request, response, mapping);
b.// Create (if necessary) a form bean to use
ActionForm instance = RequestUtils.createActionForm
(request, mapping, moduleConfig, servlet);
c.// Look up the form bean configuration information to use
String name = mapping.getName();
FormBeanConfig config = moduleConfig.findFormBeanConfig(name);
moduleConfig就是配置文件的一套操作的接口。并且FormBeanConfig也是保存在一个HashMap中,key为name,value为FormBeanConfig。返回配置信息。若不存在直接返回,因为不配置ActionForm是正确的。
ActionForm instance = lookupActionForm(request, attribute, mapping.getScope());
return createActionForm(config, servlet);
先查找在mapping.getScope()的范围(request或session)内是否存在ActionForm实例,若存在并且可用的话,直接返回这个ActionForm实例;若不存在可用ActionForm实例,则根据配置信息实例化ActionForm,并根据mapping.getScope()将ActionForm的实例保存到session或request中。
d.获取表单数据,填充ActionForm的实例:
processPopulate(request, response, form, mapping);包含:
form.reset(mapping, request);重置方法,即填充数据之前可以给From设置初始 值,此方法可以覆写。
names = request.getParameterNames();获取表单的name数组。
while(names.length){
parameterValue = request.getParameterValues(name);
properties.put(name, parameterValue);
} 迭代循环获取所有的表单数据,properties是一个HashMap。
BeanUtils.populate(form, properties);调用第三方组件,给from正式填充值。
e.// Validate any fields of the ActionForm bean, if applicable
进行一定得表单验证,调用ActionForm的public ActionErrors validate()方法,进行一定得验证,此方法可以覆写。
4.Action
// Create or acquire the Action instance to process this request
Action action = processActionCreate(request, response, mapping);
对于同一个Action,是单实例的模式,切记。
ActionForward action.execute(mapping, form, request, response)
执行execute方法,返回ActionForward。
5.根据得到的ActionForward,进行转发或重定向,返回相应的视图层。
二.问题:
1. 读取struts-config.xml文件,保存在Map中,那这个Map是作为ActionServlet的一个实例变量呢?还是存放在ServletContext里面?
我的理解:不管是作为ActionServlet的一个实例变量,还是存放在ServletContext中,都是线程不安全的。ActionServlet的init()方法读取配置文件,不管是作为ActionServlet的实例变量,还是存放在ServletContext中,都能保证它在整个应用中一直生存在内存中。
2. Action的单实例,应该怎么理解?
一个线程 --- 获取RequestProcessor processor 对象,调用process()
RequestProcessor processor = getProcessorForModule(config);
if (processor == null) {
processor = getRequestProcessor(config);
}
processor.process(request, response);
/**
* Returns the RequestProcessor for the given module or null if one does not exist. This method will not create a RequestProcessor.
* @param config The ModuleConfig.
*/
private RequestProcessor getProcessorForModule(ModuleConfig config) {
String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();
return (RequestProcessor)getServletContext().getAttribute(key);
}
protected synchronized RequestProcessor getRequestProcessor(ModuleConfig config) throws ServletException {
// 实例化RequestProcessor processor
String key = Globals.REQUEST_PROCESSOR_KEY + config.getPrefix();
getServletContext().setAttribute(key, processor);
}
config.getPrefix()是请求URI的一部分,构造一个key。这样是不是说对同一个Action的请求,只有一个RequestProcessor对象?
---- 。。。。 --- 生成Action的时候,代码片段为:
String className = mapping.getType();
synchronized (actions) {
//Return any existing Action instance of this class
instance = (Action) actions.get(className);
if (instance != null) {
return (instance);
}
try {
//Create and return a new Action instance
instance = (Action)RequestUtils.applicationInstance(className);
} catch (Exception e) {}
actions.put(className, instance);
}
protected HashMap actions = new HashMap(),actions作为类RequestProcessor 的实例变量;我的理解,由代码可以看出actions中保存的是Action的一个单实例 。。。这样的话,对于同一个Action的请求,只有一个RequestProcessor对象,只有一个Action实例,的确会出现线程安全的问题!
分享到:
相关推荐
理解Struts1的核心组件和工作原理对于任何Java Web开发者来说都是至关重要的,这有助于他们构建稳定、可扩展的应用程序。虽然Struts1已经被更现代的框架如Spring MVC取代,但其设计理念和MVC模式依然在现代Web开发中...
书中通过实例演示了如何将Struts 1应用迁移到Struts 2,使开发者能够理解两者的差异和集成方法。 Struts 2的关键特性包括: 1. **Action类与Result**:Struts 2中的Action类替代了Struts 1的Form Bean,负责处理...
在"自己实现的struts1框架 仅供参考"这个项目中,作者尝试重新创建了Struts1的核心功能,以供学习和研究之用。 首先,我们要理解Struts1的核心概念: 1. **Model**:模型层负责业务逻辑处理,通常与数据库交互。在...
本教程将帮助初学者深入理解Struts1的核心概念、工作原理以及如何使用它来构建动态Web应用程序。 **1. MVC模式** 在深入Struts1之前,首先理解MVC模式至关重要。MVC是一种设计模式,用于将业务逻辑、数据和用户界面...
这个"Struts1小demo"是一个很好的学习资源,可以帮助初学者理解Struts1的工作原理并快速上手实践。下面我们将深入探讨Struts1的相关知识点。 1. **MVC模式**:MVC模式是软件工程中的一种设计模式,将业务逻辑...
在"自己实现的struts1简易框架"中,我们看到作者试图创建一个简化版的Struts1实现,以便更好地理解和掌握其核心机制。以下是对该简易框架中涉及的关键知识点的详细解释: 1. **配置Action**: 在Struts1中,Action是...
这是对spring_hibernate_struts2的理解,可以在面试中简要的抓住重点进行陈述。
本入门案例旨在帮助初学者理解并掌握Struts1的基础用法,虽然技术含量不高,但对于理解和学习Struts1的核心概念非常有帮助。 在Struts1框架中,控制器组件主要由ActionServlet实现,它负责接收HTTP请求,并通过配置...
本实验项目旨在帮助开发者深入理解Struts1的核心概念和工作流程,以便更好地在实际开发中应用。下面我们将详细探讨Struts1的相关知识点。 1. **MVC模式**:MVC是一种设计模式,用于分离应用程序的业务逻辑、数据...
Struts1是一个经典的Java Web开发框架,由...这对于理解MVC架构和Java Web开发有着重要的价值,尽管现代Web开发更多地转向了Spring MVC和React等新技术,但掌握Struts1的基本原理仍然是提升开发者技能的重要一步。
Struts1是一个经典的Java Web开发框架,由Apache软件基金会维护,它基于Model-View-Controller(MVC)架构模式,为构建动态、数据驱动...尽管如此,理解Struts1仍然是理解现代Web框架发展历史和MVC设计模式的重要一步。
虽然Struts1.x不再是最新的框架,但它对于理解MVC设计模式以及现代Web框架的工作原理仍然具有重要的学习价值。开发者可以通过学习Struts1来掌握Web开发的基本概念,为进一步学习其他现代框架如Spring MVC或Struts2...
学习Struts1.x需要理解其设计理念,掌握配置文件的编写,熟练运用Action、ActionForm、JSP标签,以及理解MVC模式在实际开发中的应用。虽然现在Struts1.x已经被Struts2等更新的框架所取代,但它的基础思想和设计模式...
首先,我们要理解Struts1的核心概念: 1. **Action类**:在Struts1中,Action类是处理用户请求的核心组件。每个Action类对应一个特定的业务逻辑,通常会有一个与之相关的ActionForm对象来接收并验证用户输入。 2. ...
分析这些文件,可以实践Struts1的配置、开发和调试,加深对框架的理解。如果文件中包含的是示例应用,你可以运行它,观察日志,调试代码,以便更好地掌握Struts1的运作机制。 总之,Struts1作为一款历史悠久的Java ...
Struts是Apache软件基金会下的一个开源项目,主要提供MVC(Model-View-Controller...尽管Struts2在许多方面进行了改进,但Struts1仍有许多项目在使用,理解这两个框架的差异和使用方法对于Java Web开发者来说非常重要。
作为struts2的初学者,有时候理解struts框架的原理,网上看图会一头雾水,所以要是能自己体会实现struts框架的整个过程,对理解struts思路会更加清晰一些,这个源码就是自己实现的过程,代码有详细注释
总之,"struts1jar大全"提供的是一整套完整的Struts1框架运行环境,对于初学者来说,这是一个很好的起点,可以让你在实际操作中学习和理解Struts1的运作机制。通过实践,你可以逐步掌握Java Web开发的核心技术,并为...
"Struts1.3.chm"可能是针对Struts1.3版本的API文档,同样可以帮助开发者深入理解Struts1的内部机制。"struts2.pdf"可能是关于Struts2的使用指南,涵盖了从基础到高级的使用案例和最佳实践。 学习和使用这两个框架,...
Struts是Apache软件基金会下的一个开源项目,主要提供了一个用于构建企业级Java Web应用程序的MVC(Model-View-Controller)...通过学习这两本书,开发者可以深入理解这两个版本的Struts框架,提高Java Web开发能力。