1、整体结构
2.几个概念
2.1 actionContext: is the context in which an Action
is executed. Each context is basically a container of objects an action needs for execution like the session, parameters, locale, etc.
保存session,parameters等对象的是一个Map类型叫context对象。 其在内存中的快照如下:
2.2 FilterDispatcher
Master filter for Struts that handles four distinct responsibilities:
- Cleaning up the ActionContext (see note)
- Kicking off XWork's interceptor chain for the request lifecycle
Struts2.1.3之后用StrutsPrepareAndExecuteFilter 替换
2.3 Dsipatcher:
struts真正用来转发的类。
该类是线程安全的。因为它的实例是如下代码生成的
1 |
private static ThreadLocal<Dispatcher> instance = new ThreadLocal<Dispatcher>();
|
3 |
public static Dispatcher getInstance() {
|
用来处理的方法是serviceAction
1 |
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
|
2 |
ActionMapping mapping) throws ServletException
|
与Action相关的信息如name result path 在ActionMapping中。ActionMapping 的定义
1 |
public class ActionMapping {
|
3 |
private String namespace;
|
5 |
private String extension;
|
6 |
private Map<String, Object> params;
|
2.4 ActionInvocation:如何创建,执行Action。实现类DefaultActionInvocation。包含的对象有
01 |
protected Object action;
|
02 |
protected ActionProxy proxy;
|
03 |
protected List<PreResultListener> preResultListeners;
|
04 |
protected Map<String, Object> extraContext;
|
05 |
protected ActionContext invocationContext;
|
06 |
protected Iterator<InterceptorMapping> interceptors;
|
07 |
protected ValueStack stack;
|
08 |
protected Result result;
|
09 |
protected Result explicitResult;
|
10 |
protected String resultCode;
|
11 |
protected boolean executed = false ;
|
12 |
protected boolean pushAction = true ;
|
13 |
protected ObjectFactory objectFactory;
|
14 |
protected ActionEventListener actionEventListener;
|
15 |
protected ValueStackFactory valueStackFactory;
|
16 |
protected Container container;
|
17 |
private Configuration configuration;
|
18 |
protected UnknownHandlerManager unknownHandlerManager;
|
核心方法是invoke()
1 |
interceptor.getInterceptor().intercept(DefaultActionInvocation. this );
|
其中invokeActionOnly(Object action, ActionConfig actionConfig)调用Action中对应的方法为:
3 |
method = getAction().getClass().getMethod(methodName, EMPTY_CLASS_ARRAY);
|
7 |
methodResult = method.invoke(action, new Object[ 0 ]);
|
创建Action: createAction(Map<String, Object> contextMap)
1 |
action = objectFactory.buildAction(proxy.getActionName(), proxy.getNamespace(), proxy.getConfig(), contextMap); |
3 |
if (actionEventListener != null ) {
|
4 |
action = actionEventListener.prepare(action, stack);
|
2.5 ActionProxy:怎么找到Action:存放actionName 和ActionInvocation对象。在ActionInvocation对象的初始化时创建Action:init(ActionProxy proxy) 中调用createAction(contextMap); struts中默认的实现类是StrutsActionProxy
2.6 ObjectFactory
ObjectFactory is responsible for building the core framework objects. Users may register their own implementation of the ObjectFactory to control instantiation of these Objects.
This default implementation uses the buildBean
method to create all classes (interceptors, actions, results, etc).
buildBean(config.getClassName(), extraContext)这个方法做的事情很简单:用ClassLoader加载classname所对应的class,extraContext这个参数没有用到。
2.7 ConfigurationManager - central for XWork Configuration management, including its ConfigurationProvider.
2.8 ConfigurationProvider interface describes the framework's configuration. By default, the framework loads its configurations via an xml document by using the StrutsXmlConfigurationProvider.
3、简单步骤
客户端提起一个(HttpServletRequest)请求,如上文在浏览器中输入”http://localhost:8080/TestMvc/add.action”就是提起一个(HttpServletRequest)请求。
- 请求被提交到一系列(主要是三层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器(SiteMesh等)、 FilterDispatcher)。注意这里是有顺序的,先ActionContextCleanUp,再其他过滤器(SiteMesh等)、最后到FilterDispatcher。
- FilterDispatcher是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解的FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter
其代码如下:
-
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException ...{
- HttpServletRequest request = (HttpServletRequest) req;
- HttpServletResponse response = (HttpServletResponse) res;
- ServletContext servletContext = filterConfig.getServletContext();
-
- DispatcherUtils du = DispatcherUtils.getInstance();
-
du.prepare(request, response);
-
try ...{
-
request = du.wrapRequest(request, servletContext);
-
} catch (IOException e) ...{
-
String message = "Could not wrap servlet request with MultipartRequestWrapper!";
- LOG.error(message, e);
-
throw new ServletException(message, e);
- }
-
ActionMapperIF mapper = ActionMapperFactory.getMapper();
-
ActionMapping mapping = mapper.getMapping(request);
-
if (mapping == null) ...{
-
- String resourcePath = RequestUtils.getServletPath(request);
-
if ("".equals(resourcePath) && null != request.getPathInfo()) ...{
- resourcePath = request.getPathInfo();
- }
-
if ("true".equals(Configuration.get(WebWorkConstants.WEBWORK_SERVE_STATIC_CONTENT))
-
&& resourcePath.startsWith("/webwork")) ...{
-
String name = resourcePath.substring("/webwork".length());
- findStaticResource(name, response);
-
} else ...{
-
- chain.doFilter(request, response);
- }
-
-
return;
- }
-
Object o = null;
-
try ...{
-
- o = beforeActionInvocation(request, servletContext);
- du.serviceAction(request, response, servletContext, mapping);
-
} finally ...{
- afterActionInvocation(request, servletContext, o);
-
ActionContext.setContext(null);
- }
- }
- du.serviceAction(request, response, servletContext, mapping);
-
-
public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) ...{
-
HashMap extraContext = createContextMap(requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig());
-
extraContext.put(SERVLET_DISPATCHER, this);
- OgnlValueStack stack = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);
-
if (stack != null) ...{
-
extraContext.put(ActionContext.VALUE_STACK,new OgnlValueStack(stack));
- }
-
try ...{
- ActionProxy proxy = ActionProxyFactory.getFactory().createActionProxy(namespace, actionName, extraContext);
- request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());
- proxy.execute();
-
-
if (stack != null)...{
- request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack);
- }
-
} catch (ConfigurationException e) ...{
-
log.error("Could not find action", e);
- sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
-
} catch (Exception e) ...{
-
log.error("Could not execute action", e);
- sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
- }
- }
-
FilterDispatcher询问ActionMapper是否需要调用某个Action来处理这个(request)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。
- ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类.
如上文的struts.xml配置
-
<?xml version="1.0" encoding="GBK"?>
-
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
-
<struts>
-
<include file="struts-default.xml"/>
-
<package name="struts2" extends="struts-default">
-
<action name="add"
-
class="edisundong.AddAction" >
-
<result>add.jsp</result>
-
</action>
-
</package>
-
</struts>
-
如果提交请求的是add.action,那么找到的Action类就是edisundong.AddAction。
- ActionProxy创建一个ActionInvocation的实例,同时ActionInvocation通过代理模式调用Action。但在调用之前ActionInvocation会根据配置加载Action相关的所有Interceptor。(Interceptor是struts2另一个核心级的概念)
下面我们来看看ActionInvocation是如何工作的:
ActionInvocation 是Xworks 中Action 调度的核心。而对Interceptor 的调度,也正是由ActionInvocation负责。ActionInvocation 是一个接口, 而DefaultActionInvocation 则是Webwork 对ActionInvocation的默认实现。
Interceptor 的调度流程大致如下:
1. ActionInvocation初始化时,根据配置,加载Action相关的所有Interceptor。
2. 通过ActionInvocation.invoke方法调用Action实现时,执行Interceptor。
Interceptor将很多功能从我们的Action中独立出来,大量减少了我们Action的代码,独立出来的行为具有很好的重用性。XWork、WebWork的许多功能都是有Interceptor实现,可以在配置文件中组装Action用到的Interceptor,它会按照你指定的顺序,在Action执行前后运行。
那么什么是拦截器。
拦截器就是AOP(Aspect-Oriented Programming)的一种实现。(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。)
拦截器的例子这里就不展开了。
struts-default.xml文件摘取的内容:
-
< interceptor name ="alias" class ="com.opensymphony.xwork2.interceptor.AliasInterceptor" />
-
< interceptor name ="autowiring" class ="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor" />
-
< interceptor name ="chain" class ="com.opensymphony.xwork2.interceptor.ChainingInterceptor" />
-
< interceptor name ="conversionError" class ="org.apache.struts2.interceptor.StrutsConversionErrorInterceptor" />
-
< interceptor name ="createSession" class ="org.apache.struts2.interceptor.CreateSessionInterceptor" />
-
< interceptor name ="debugging" class ="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" />
-
< interceptor name ="external-ref" class ="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor" />
-
< interceptor name ="execAndWait" class ="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor" />
-
< interceptor name ="exception" class ="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor" />
-
< interceptor name ="fileUpload" class ="org.apache.struts2.interceptor.FileUploadInterceptor" />
-
< interceptor name ="i18n" class ="com.opensymphony.xwork2.interceptor.I18nInterceptor" />
-
< interceptor name ="logger" class ="com.opensymphony.xwork2.interceptor.LoggingInterceptor" />
-
< interceptor name ="model-driven" class ="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor" />
-
< interceptor name ="scoped-model-driven" class ="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor" />
-
< interceptor name ="params" class ="com.opensymphony.xwork2.interceptor.ParametersInterceptor" />
-
< interceptor name ="prepare" class ="com.opensymphony.xwork2.interceptor.PrepareInterceptor" />
-
< interceptor name ="static-params" class ="com.opensymphony.xwork2.interceptor.StaticParametersInterceptor" />
-
< interceptor name ="scope" class ="org.apache.struts2.interceptor.ScopeInterceptor" />
-
< interceptor name ="servlet-config" class ="org.apache.struts2.interceptor.ServletConfigInterceptor" />
-
< interceptor name ="sessionAutowiring" class ="org.apache.struts2.spring.interceptor.SessionContextAutowiringInterceptor" />
-
< interceptor name ="timer" class ="com.opensymphony.xwork2.interceptor.TimerInterceptor" />
-
< interceptor name ="token" class ="org.apache.struts2.interceptor.TokenInterceptor" />
-
< interceptor name ="token-session" class ="org.apache.struts2.interceptor.TokenSessionStoreInterceptor" />
-
< interceptor name ="validation" class ="com.opensymphony.xwork2.validator.ValidationInterceptor" />
-
< interceptor name ="workflow" class ="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor" />
-
< interceptor name ="store" class ="org.apache.struts2.interceptor.MessageStoreInterceptor" />
-
< interceptor name ="checkbox" class ="org.apache.struts2.interceptor.CheckboxInterceptor" />
-
< interceptor name ="profiling" class ="org.apache.struts2.interceptor.ProfilingActivationInterceptor" />
-
一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。如上文中将结构返回“add.jsp”,但大部分时候都是返回另外一个action,那么流程又得走一遍………
总结:
Struts2的工作流就只有这7步,比起Struts1简单了很多(本人能力有限,struts2更多的东西现在还看不明白)。网上有很多很多的关于.net和java的比较之类的文章,可是有几个作者是真正用过java和.net的呢?更多的评论都是人云亦云,想当然的评论java和.net。作为技术人千万不要屁股决定脑袋,关于web的设计模式上.net也不是那么一无是处,java也不是那么完美无缺
分享到:
相关推荐
本书是广受赞誉的Struts 2优秀教程,它全面而深入地阐述了Struts 2的各个特性,并指导开发人员如何根据遇到的问题对症下药,选择使用最合适的特性。作者处处从实战出发,在丰富的示例中直观地探讨了许多实用的技术,...
2.2 Struts的动作处理流程 15 2.3 拦截器 17 2.4 Struts配置文件 18 2.4.1 struts.xml文件 19 2.4.2 struts.properties文件 26 2.5 Struts应用程序示例 26 2.5.1 部署描述文件和Struts配置文件 27 2.5.2 动作类 28 ...
使用struts增加学生,用于描述简单的流程分析
1.Model1和Model2简介2.Struts的结构和处理流程简介3.利用Struts框架开发MVC系统要做的工作4.可供参考的例子参考资料关于作者1.Model1和Model2简介我们在开发Web应用时经常提到的一个概念是Model1/Model2,那么...
2. 深入 STRUTS架构..................................................................................37 2.1. 随便谈谈......................................................................................
2. 深入STRUTS 架构..................................................................................37 2.1. 随便谈谈.......................................................................................
2.1.1 Struts2框架技术 3 2.2.2 Hibernate框架技术 4 2.3 开发工具介绍 5 2.3.1 MyEclipse介绍 5 2.3.2 MySQL5.0介绍 5 3 需求分析 6 3.1 可行性分析 6 3.2 功能需求 6 3.3 性能需求 7 3.4 数据需求 7 3.5 数据字典 ...
2.1.1 Struts2框架技术 3 2.2.2 Hibernate框架技术 4 2.3 开发工具介绍 5 2.3.1 MyEclipse介绍 5 2.3.2 MySQL5.0介绍 5 3 需求分析 6 3.1 可行性分析 6 3.2 功能需求 6 3.3 性能需求 7 3.4 数据需求 7 3.5 数据字典 ...
124 8.5.2 拦截器的实现原理 124 8.5.3 Struts2的内置拦截器 124 8.5.4 拦截器的配置和使用 125 8.5.5 自定义拦截器 126 8.6 一个简单的Struts2应用 130 8.7 小结 140 第9章 JSF 141 9.1 JSF技术简介 141 9.1.1 JSF...
Struts的优势: 1、表现欲逻辑分离,使开发流程和架构更加合理; 2、Struts为系统开发人员提供了充分的扩展机制,维护扩展比较方便; 3、业界"标准",学习资源丰富,HTML标签优秀。 当然,Struts也有它的缺点: 1、...
Struts如何实现Model 2, MVC 639 Struts 控制流 639 Struts framework的工作原理和组件 642 Struts ActionServlet控制器对象 642 Struts Action Classes 642 搞定Action对象 643 处理异常 643 Action的分类 643 ...
59. 请对以下在J2EE中常用的名词进行解释(或简单描述) 40 59.1. web 容器 40 59.2. EJB容器 40 59.3. JNDI 40 59.4. JMS 41 59.5. JTA 41 59.6. JAF 41 59.7. RMI/IIOP 41 60. JAVA语言如何进行异常处理,关键字:...
Struts的工作流程: 在web应用启动时就会加载初始化ActionServlet,ActionServlet从 struts-config.xml文件中读取配置信息,把它们存放到各种配置对象 当ActionServlet接收到一个客户请求时,将执行如下流程. -(1)检索和...
主要技术包括:Hibernate、Spring、SpringMVC、log4j slf4j 整合、myBatis、struts2、Shiro 、redis、流程引擎activity, 爬 ⾍技术nutch,lucene,webService CXF、Tomcat集群和热备 、MySQL读写分离 4. 描述如下:...
6、请对以下在J2EE中常用的名词进行解释(或简单描述) 129 7、如何给weblogic指定大小的内存? 129 8、如何设定的weblogic的热启动模式(开发模式)与产品发布模式? 129 9、如何启动时不需输入用户名与密码? 130 10、...
6、请对以下在J2EE中常用的名词进行解释(或简单描述) 7、如何给weblogic指定大小的内存? 8、如何设定的weblogic的热启动模式(开发模式)与产品发布模式? 9、如何启动时不需输入用户名与密码? 10、在weblogic管理制...