对struts2的原理、结构、配置做一个总结,算是给总结的一个阶段复习材料
原理部分:
万变不离其宗,对这句话深信不疑,掌握原理远比掌握框架要来的长远的多,框架作为一款特殊的产品,终究会随着时代更迭
1 web应用程序流程:
所有的互联网应用都是基于请求/应答机制(request/response)的,互联网发展到现在这个机制也是非常合理的~~而我们常用来发送的请求的载体一般是浏览器,当然它是user-agent的一种,其他的还有各种能与互联网通信的应用都算。user-agent把http请求(包括请求方式和请求体)通过URL来发送给指定的服务器,服务器接收后进行相应处理并返回 应答状态(是否请求成功,是否存在要的资源等)+资源(最开始是页面,后来是媒体,现在则是混杂的各类数据),user-agent接收到应答后 解析并最终显示到用户前。现在可以很容易的为什么把浏览器这些能与互联网通信的应用叫做user-agent了,因为作为用户的人类是无法完成这个的,你难道会对着电脑大吼:把这个请求发送给某某某吗?而user-agent正如它的名称一样,作为代理帮助我们完成与互联网(一堆机器及机器后的人)的沟通。(实际上所有代理我们都可以这样理解,从翻墙用的ip代理到struts2的ActionProxy)
页面提交请求——服务器接收请求——处理请求——返回处理结果——用户接收到结果
下面给出请求体的标准格式和应答的标准格式便于理解,下图引自:http://www.tcpipguide.com/free/t_HTTPRequestMessageFormat.htm(提供更多关于互联网协议的知识)
一般用到的是:请求行,请求头,请求体;在struts2中,数据通过form表单提交或者通过超链接等其他方式,请求方法为post/get,url为请求的资源地址,也就是所请求的action
在form表单中提交:
<form action="/web/user/register.action" method="post">
</form>
在struts2中,web应用程序的流程也是如此
下面放上一张大家“耳熟能详”的流程图:
2 数据流程
①用户页面通过浏览器发送http请求给web容器(比如Tomcat、Jboss等)
②请求先由容器来接收,然后根据web.xml再给基于这个容器的框架
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
③struts2(webwork)的核心机制:FilterDispatcher过滤适配器
StrutsPrepareAndExecuteFilter类中执行doFilter()方法,在里面通过ActionMapping获取配置action的信息
request = prepare.wrapRequest(request);
ActionMapping mapping = prepare.findActionMapping(request, response, true);
if (mapping == null) {
boolean handled = execute.executeStaticResourceRequest(request, response);
if (!handled) {
chain.doFilter(request, response);
}
} else {
execute.executeAction(request, response, mapping);
}
④execute执行executeAction()调用Dispatcher中的serviceAction()方法,该方法通过ValueStack获取数据,【反射机制】动态实例化ActionProxy接口(位于xwork-core包下)
Configuration config = configurationManager.getConfiguration();
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
namespace, name, method, extraContext, true, false);
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
⑤使用代理来执行相应的action,在action中需要涉及数据库的——Service调用数据库访问层Dao来获取要请求的数据——不需要访问数据的请求则在action中处理完毕
⑥最后都会返给result中配置的视图比如某个页面或某个action
if (mapping.getResult() != null) {
Result result = mapping.getResult();
result.execute(proxy.getInvocation());
} else {
proxy.execute();
}
至此一个简单的流程完毕